부스트랩 무료 테마 모아둔 사이트
- http://www.bootstrapstage.com/free-themes/
관리자 페이지 작업할때 쓰면 좋은 템플릿도 많다!! 나중에 참고하기~!
부스트랩 무료 테마 모아둔 사이트
- http://www.bootstrapstage.com/free-themes/
관리자 페이지 작업할때 쓰면 좋은 템플릿도 많다!! 나중에 참고하기~!
Rest API 처음 설계할때 참고하면 좋은 블로그 많은 도움되었음
조대협님의 블로그
REST API 이해와 설계 - #1 개념 잡기 - http://bcho.tistory.com/953
REST API 이해와 설계 - #2 디자인 가이드 - http://bcho.tistory.com/954
REST API 이해와 설계 - #3 보안 가이드 - http://bcho.tistory.com/955
깔끔하게 잘 정리 해놓아서 참고 하기 좋은 블로그
RestFul이란 무엇인가? - http://blog.remotty.com/blog/2014/01/28/lets-study-rest/
restful api 만들려고 하는 데 페이지(URI)별 따로 모듈로 빼서 작업할 때
routes module.exports 할때 매번 해당 모듈페이지에서 DB커넥션 작업 해야되나 고민하는데...
app.js에서 최초 한번 커넥션풀 유지해서 하는 방법에 대해서 어떻게 하나 예시 찾던 중 해결책 발견
참고사이트 : http://cwbuecheler.com/web/tutorials/2014/restful-web-app-node-express-mongodb/
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
// Database
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/nodetest2", {native_parser:true});
/ Make our db accessible to our router
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', routes);
app.use('/users', users);
routes 위에다가 requset 정보에 db 커넥션풀 정보를 포함하게 정의하고 next 실행그리고 각각의 routes 모듈에 보낼 수 있다DB 커넥션풀 정보 필요없는 routes는 알아서 제외하면될 듯
node.js에서 간략하게 IP기반으로 사용자 (위치) 지역 정보 데이터 분석용으로 GeoIP 라이브러리 있나 찾아봤음
역시 라이브러리 geoip-lite 라고 있음!!
Github : https://github.com/bluesmoon/node-geoip
1. 설치방법
$ npm install geoip-lite
2. 코드작성 및 사용법
$ vi geoip.js ===================================== var geoip = require('geoip-lite'); var ip = "207.97.227.239"; var geo = geoip.lookup(ip); console.log(geo); ==================================== $ node geoip.js { range: [ 3479297920, 3479301339 ], country: 'US', region: 'TX', city: 'San Antonio', ll: [ 29.4889, -98.3987 ], metro: 641 }
※ ll 배열값에서 ll: [<latitude(위도)>, <longitude(경도)>] 순서임!!
3. GeoIP 정보 업데이트방법
※ github보면 geoip.startWatchingDataUpdate(); 함수로도 가능한데 아래 script로 하는게 더 낫은듯함
$ cd /usr/lib/node_modules/geoip-lite $ npm run-script updatedb > geoip-lite@1.1.5 updatedb /usr/lib/node_modules/geoip-lite > node scripts/updatedb.js Retrieving GeoIPCountryCSV.zip ... DONE Extracting GeoIPCountryCSV.zip ... DONE Processing Data (may take a moment) ... Still working (96813) ... DONE Retrieving GeoIPv6.csv ... DONE Processing Data (may take a moment) ... DONE Retrieving GeoLiteCity-latest.zip ... DONE Extracting GeoLiteCity-latest.zip ... DONE Processing Data (may take a moment) ... Still working (122762) ... Still working (246870) ... Still working (368626) ... Still working (490380) ... Still working (612413) ... Still working (734688) ... Still working (855126) ... Still working (977268) ... Still working (1096307) ... Still working (1217573) ... Still working (1339167) ... Still working (1459608) ... Still working (1580033) ... Still working (1700173) ... Still working (1822030) ... Still working (1943449) ... DONE Retrieving GeoLiteCityv6.csv ... DONE Processing Data (may take a moment) ... DONE Successfully Updated Databases from MaxMind.
※ https://github.com/PaddeK/node-maxmind-db 추가 라이브러리(동일하게 MaxMind DB 기반이긴함)
elasticsearch Bulk insert(put) 대량 데이터 입력하기
공식 가이드 API : http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html
1) 데이터 파일 생성
$ vi put_data { "index":{ "_index" : "logstash-2015.03.06", "_type" : "access_log", "_id" : "1" } } { "host":"web01","http_host": "192.168.1.123"} { "index":{ "_index" : "logstash-2015.03.06", "_type" : "access_log", "_id" : "2" } } { "host":"web01","http_host": "192.168.1.124"}
2) Curl Post 로 전송
$ curl -s -XPOST localhost:9200/_bulk --data-binary @put_data {"took":317,"errors":false,"items":[{"index":{"_index":"logstash-2015.03.06","_type":"access_log","_id":"1","_version":1,"status":201}},{"index":{"_index":"logstash-2015.03.06","_type":"access_log","_id":"2","_version":1,"status":201}}]}
3) 데이터 확인
$ curl -XGET localhost:9200/logstash-2015.03.06/access_log/1 {"_index":"logstash-2015.03.06","_type":"access_log","_id":"1","_version":1,"found":true,"_source":{ "host":"web01","http_host": "192.168.1.123"}} $ curl -XGET localhost:9200/logstash-2015.03.06/access_log/2 {"_index":"logstash-2015.03.06","_type":"access_log","_id":"2","_version":1,"found":true,"_source":{ "host":"web01","http_host": "192.168.1.124"}}
4) index와 type이 동일하다면 url쓰고 제외해도됨
$ vi put_data
{ "index":{ "_id" : "1" } }
{ "host":"web01","http_host": "192.168.1.123"}
{ "index":{ "_id" : "2" } }
{ "host":"web01","http_host": "192.168.1.124"}
$ curl -s -XPOST localhost:9200/logstash-2015.03.06/access_log/_bulk --data-binary @put_data
{"took":321,"errors":false,"items":[{"index":{"_index":"logstash-2015.03.06","_type":"access_log","_id":"1","_version":1,"status":201}},{"index":{"_index":"logstash-2015.03.06","_type":"access_log","_id":"2","_version":1,"status":201}}]}
※ UDP 방식도 있는 듯한데 2.0에서 삭제될 예정이라고함
Bulk UDP has been deprecated and will be removed in Elasticsearch 2.0. You should use the standard bulk API instead.
Curl 참조해서 다른 스크립트 언어에서도 POST 로 방식으로 짜면될듯함
node.js의 경우 라이브러리 활용하면 될 듯 : https://github.com/phillro/node-elasticsearch-client
//Bulk index example var commands = [] commands.push({ "index" : { "_index" :'my_index_name', "_type" : "my_type_name"} }) commands.push({field1:'value',field2:'value'}) elasticSearchClient.bulk(commands, {}) .on('data', function(data) {}) .on('done', function(done){}) .on('error', function(error){}) .exec();
elasticsearch index templates 만들기
가이드 : http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-templates.html
1. GET을 이용한 저장된 전체 인덱스 템플릿가져오기
$ curl -XGET localhost:9200/_template/ {"logstash":{"order":0,"template":"logstash-*","settings":{"index.refresh_interval":"5s"},"mappings":{"_default_":{"dynamic_templates":[{"string_fields":{"mapping":{"index":"analyzed","omit_norms":true,"type":"string","fields":{"raw":{"index":"not_analyzed","ignore_above":256,"type":"string"}}},"match_mapping_type":"string","match":"*"}}],"properties":{"geoip":{"dynamic":true,"path":"full","properties":{"location":{"type":"geo_point"}},"type":"object"},"@version":{"index":"not_analyzed","type":"string"}},"_all":{"enabled":true}}},"aliases":{}},"nginx_log":{"order":0,"template":"nginx_log-*","settings":{"index.refresh_interval":"5s"},"mappings":{"_default_":{"dynamic_templates":[{"string_fields":{"mapping":{"index":"analyzed","omit_norms":true,"type":"string","fields":{"raw":{"index":"not_analyzed","ignore_above":256,"type":"string"}}},"match":"*","match_mapping_type":"string"}}],"properties":{"geoip":{"dynamic":true,"path":"full","properties":{"location":{"type":"geo_point"}},"type":"object"},"@version":{"index":"not_analyzed","type":"string"}},"_all":{"enabled":true}}},"aliases":{}}}
※ 2개 logstash / nginx_log 두개 인덱스 템플릿 등록된게 보인다
2. GET을 이용해서 하나만 지정해서 보기
$ curl -XGET localhost:9200/_template/nginx_log {"nginx_log":{"order":0,"template":"nginx_log-*","settings":{"index.refresh_interval":"5s"},"mappings":{"_default_":{"dynamic_templates":[{"string_fields":{"mapping":{"index":"analyzed","omit_norms":true,"type":"string","fields":{"raw":{"index":"not_analyzed","ignore_above":256,"type":"string"}}},"match":"*","match_mapping_type":"string"}}],"properties":{"geoip":{"dynamic":true,"path":"full","properties":{"location":{"type":"geo_point"}},"type":"object"},"@version":{"index":"not_analyzed","type":"string"}},"_all":{"enabled":true}}},"aliases":{}}}
3. PUT 신규 템플릿 신규 등록
$ curl -XPUT localhost:9200/_template/nginx_log2 -d ' > { > "order":0, > "template":"nginx_log2-*", > "settings":{ > "index.refresh_interval":"5s" > }, > "mappings":{ > "_default_":{ > "dynamic_templates":[{ > "string_fields":{ > "mapping":{ > "index":"analyzed", > "omit_norms":true, > "type":"string", > "fields":{ > "raw":{ > "index":"not_analyzed", > "ignore_above":256, > "type":"string" > } > } > }, > "match_mapping_type":"string", > "match":"*" > } > } > ], > "properties":{ > "geoip":{ > "dynamic":true, > "path":"full", > "properties":{ > "location":{ > "type":"geo_point" > } > }, > "type":"object" > }, > "@version":{ > "index":"not_analyzed", > "type":"string" > } > }, > "_all":{ > "enabled":true > } > } > }, > "aliases":{ > } > }' {"acknowledged":true}
4. DELETE 템플릿 삭제
$ curl -XDELETE localhost:9200/_template/nginx_log2
{"acknowledged":true}
이것 외에도 GET할때 여러개 템플릿 같이 보기등 가이드사이트 가면 몇가지 예시 더 있음 참고할것!~
Elasticsearch node.js를 이용해서 데이터 입력(PUT) 하기
logstash이 잘되어있어서 패턴 잘구성해서 logstash을 이용해도 되지만 logstash패턴 사용하는 법을 좀 봐야되고...
잘 사용법도 모르는 환경에서 계속 서비스 RDBMS에 커넥션 유지하는 것도 부담스러워서 따로 node.js로 짜기로함
기본적으로 콘솔에서 curl 날리는 예시는 아래와 같음
$ curl -XPUT 'http://localhost:9200/logstash-2015.03.06/access_log/1' -d '{ > "host": "web01", > "http_host": "192.168.1.123", > "clientip": "192.2.3.55", > "timestamp": "Fri Feb 06 2015 14:04:22 GMT+0900 (KST)", > "verb": "GET", > "request": "/css/comm.css", > "httpversion": "1.1", > "response": "304", > "bytes": "0", > "referrer": "http://192.168.1.124/", > "agent": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17", > "request_time": 0 > }'
등록 결과 아래와 같이 나온걸 볼 수 있다
{"_index":"logstash-2015.03.06","_type":"access_log","_id":"1","_version":1,"created":true}
브라우져에서 head 들어가보면 확인 가능하다.
http://localhost:9200/_plugin/head/
이걸 node.js http라이브러리이용하면 간단하다.
var http = require('http'); function elasticsearchPut(index,type,id,put_data){ var option = { hostname: 'localhost', port: 9200, path: '/'+index+'/'+type+'/'+id, method: 'PUT' }; var req = http.request(option, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log(chunk); }); }); req.on('error', function(e) { console.log('problem with request: ' + e.message); }); // DATA PUT req.write(JSON.stringify(put_data)); req.end(); } var index = 'logstash-2015.03.06'; var type = 'access_log'; var id = 2; var data = { "host": "web01", "http_host": "192.168.1.123", "clientip": "192.2.3.55", "timestamp": "Fri Feb 06 2015 14:04:22 GMT+0900 (KST)", "verb": "GET", "request": "/css/comm.css", "httpversion": "1.1", "response": "304", "bytes": "0", "referrer": "http://192.168.1.124/", "agent": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17", "request_time": 0 }; elasticsearchPut(index,type,id,data);
콘솔에서 실행하면 아래와 같이 결과 메세지를 동일하게 볼 수 있다.
$ node test.js STATUS: 201 HEADERS: {"content-type":"application/json; charset=UTF-8","content-length":"91"} {"_index":"logstash-2015.03.06","_type":"access_log","_id":"2","_version":1,"created":true}
예시로 nginx access_log로 했는데 실제 사용하는데는 이벤트나 구매내역등 실제 서비스로그를 RDBMS에서 주기적으로 가져와서 분석하는 용도로 사용함
추가적 node.js 라이브러리 및 Bulk insert 참고
각 툴에 대한 설명
1) elasticsearch => JAVA Lucene기반의 검색엔진
URL : http://www.elasticsearch.org/
Github : https://github.com/elasticsearch/elasticsearch
2) logstash => 실시간으로 다양한 로그를 가져와서 elasticsearch 넣어주는 역할
URL : http://logstash.net/
Github : https://github.com/elasticsearch/logstash
※ logstash 경우 꼭 elasticsearch와 연동하지 않더라도 다양한 어플리케이션 로그를 input으로 받아서 다른 저장소로 전달하는 ouput 작업을 하기 위해서 쓰기 좋은 듯하다.
3) Kibana => elasticsearch와 연동해서 시각적으로 볼 수 있게 해주는 툴 node.js기반임
URL : http://www.elasticsearch.org/overview/kibana/
Github : https://github.com/elasticsearch/kibana
설치 및 실행가이드
1. JAVA설치 - elasticsearch 사용하기 위해서 필요
$ yum install java ================================================== Package Arch ================================================== Installing: java-1.7.0-openjdk x86_64 Installing for dependencies: flac x86_64 giflib x86_64 jpackage-utils noarch libasyncns x86_64 libsndfile x86_64 pulseaudio-libs x86_64 ttmkfdir x86_64 tzdata-java noarch xorg-x11-fonts-Type1 noarch Transaction Summary ================================================== Install 10 Package(s)
2. elasticsearch 설치 및 실행
$ wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.4.tar.gz $ tar xvfz elasticsearch-1.4.4.tar.gz $ cd elasticsearch-1.4.4/bin $ ./elasticsearch -d $ ps aux | grep elasticsearch
※ 옵션 -d 데몬으로 백그라운드실행
※ ElasticSearch 모니터링 추가 Plugin 설치
$ ./plugin -install mobz/elasticsearch-head
=> URL : http://localhost:9200/_plugin/head/
$ ./plugin -install lukas-vlcek/bigdesk
=> URL : http://localhost:9200/_plugin/bigdesk/
$ ./plugin -install lmenezes/elasticsearch-kopf
=> URL : http://localhost:9200/_plugin/kopf/
3. Logstash 설치
$ wget https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz $ tar xvfz logstash-1.4.2.tar.gz
※ 테스트 Nginx Access Log 추가
1) nginx.conf 로그구조 수정 후 Nginx 재시작
http { log_format main '$http_host ' '$remote_addr [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time ' '$upstream_response_time'; access_log /var/log/nginx/access.log main; }
2) nginx 패턴 추가
$ vi ./logstash-1.4.2/patterns/nginx
NGUSERNAME [a-zA-Z\.\@\-\+_%]+ NGUSER %{NGUSERNAME} NGINXACCESS %{IPORHOST:http_host} %{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float} %{NUMBER:upstream_time:float} NGINXACCESS %{IPORHOST:http_host} %{IPORHOST:clientip} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NUMBER:request_time:float
$ vi ./logstash-1.4.2/log_list/nginx.conf
====================================================== input { file { path => "/var/log/nginx/access.log" } } filter { mutate { replace => { "type" => "nginx_access" } } grok { match => { "message" => "%{NGINXACCESS}" } } date { match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ] } geoip { source => "clientip" } } output { elasticsearch { host => localhost port => 9200 protocol => http } stdout { codec => rubydebug } }
※ 데이터 읽어와서 NGINXACCESS 매칭해서 elasticsearch로 보내는 설정정보이다
elasticsearch 외에도 logstash의 경우 다양한 input output방식으로 데이터를 실시간 전달가능하다.
※ protocol 디폴트가 node이므로 버젼에 따라서 Kibana 사용할려면 http 설정해줘야될 경우도 있다
자세한 내용 참고 : http://logstash.net/docs/1.4.2/outputs/elasticsearch
$ ../bin/logstash -f nginx.conf -t Configuration OK
5) logstash 실행
$ ../bin/logstash -f nginx.conf { "message" => "192.168.25.111 192.0.0.30 [02/Mar/2015:15:10:37 +0900] \"GET /favicon.ico HTTP/1.1\" 404 3652 \"-\" \"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17\" 0.000 -", "@version" => "1", "@timestamp" => "2015-03-02T06:10:37.000Z", "host" => "testServer01", "path" => "/var/log/nginx/access.log", "type" => "nginx_access", "http_host" => "192.168.25.111", "clientip" => "192.0.0.30", "timestamp" => "02/Mar/2015:15:10:37 +0900", "verb" => "GET", "request" => "/favicon.ico", "httpversion" => "1.1", "response" => "404", "bytes" => "3652", "referrer" => "\"-\"", "agent" => "\"Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17\"", "request_time" => 0.0 }
※ elasticsearch-head 설치했다면 http://localhost:9200/_plugin/head/ 데이터 확인
4. Kibana 설치
$ wget https://download.elasticsearch.org/kibana/kibana/kibana-4.0.0-linux-x64.tar.gz $ tar xvfz kibana-4.0.0-linux-x64.tar.gz $ cd kibana-4.0.0-linux-x64
$ vi config/kibana.yml ====================================================== # Kibana is served by a back end server. This controls which port to use. port: 5601 # The Elasticsearch instance to use for all your queries. elasticsearch_url: "http://localhost:9200"
※ 설치법 찾아보면 kibana_index: "logstash-*" 인덱스 수정하라고 하는 듯한데 logstash-*로 인덱스 잡아주면 아래 에러 나면서 사이트 접속이 안됨.....
Fatal Error Courier Fetch Error: unhandled error Error: Request to Elasticsearch failed: {"_index":"logstash-*","_type":"config","_id":"4.0.0","error":"[logstash-*] missing"}
그래서 kibana_index: ".kibana" 그대로 유지하였더니 잘됨... 보니까 kibana_index란 셋팅하는 대쉬보드 정보 저장하는 저장소의 정보인듯함... 검색 인덱스 셋팅은 kibana 접속후에 아래와같이 Configure an index pattern에서 index 추가하면됨
2) 최종적으로 웹브라우져 켜서 config 에 설정한 port 로 접속하면됨
- http://server_ip:5601
※ visualization 과 Dashboard 설정하는 부분은 나중에 시간있을때 추가하는걸로~!!
node.js socket.io의 cluster 사용 참고사항
기본적으로 클라이언트가 transports: ['websocket'] 기반으로만 사용한다면 문제가 되지 않는다
하지만 XHR Polling 또는 JSONP Polling 사용시에는
{"code":1,"message":"Session ID unknown"}
문제가 발생한다
폴링은 여러번 요청을 보내는데 여러 process중에 같은 process로 붙을 수 없어서 Session ID 찾을수 없는 듯하다
그래서
http://socket.io/docs/using-multiple-nodes/
메뉴얼 사이트에 보면 제시하는 방법이
1. NginX configuration
node.js에서 제공되는 cluster를 사용하지 않고 NginX를 앞단에 둔다
그리고 upstream 을 통해서 프록시 서버를 둔다 그리고 ip_hash 를 설정해서 같은 ip의 경우 같은 포트(즉같은프로세스)를 보도록 해서 문제를 해결한다
※ node.js socket.io는 데몬을 각각 포트별로 여러개 띄워야된다.
2. Using Node.JS Cluster
추가로 node.js Cluster 사용시에는 https://github.com/indutny/sticky-session
(나도 아직 테스트 제대로 해보지 않았음)
3. Passing events between nodes
그리고 클러스터 구성시에 유저들간의 메세지(이벤트) 전달은 https://github.com/automattic/socket.io-redis
socket.io-redis이용해서 가능한 방법을 제공해주고있다
테스트해보니까 다른 node 프로세스로 붙어있지만 아래 명령어 실행시 이상없이 잘 동작한다.
socket.broadcast.emit / 자신제외 전체유저
io.sockets.in(socket_id).emit / 특정유저에게메세지전달
socket.broadcast.to(room_id).emit / 같은 룸에 입장된 유저에게 메세지전달
추가로 용량 처리가 많을 경우 detect_buffers 옵션을 true 해줘야됨
var redis = require("redis"); var redisAdapter = require('socket.io-redis'); var pub = redis.createClient("/tmp/redis.sock",{ detect_buffers: true }); var sub = redis.createClient("/tmp/redis.sock",{ detect_buffers: true }); io.adapter( redisAdapter({pubClient: pub, subClient: sub}) );
※ socket.io 서비스 하기 위해서 유저별 socket.id를 관리하는 redis 와 서비스 비지니스 로직에 적절한 cluster 기능을 잘 구성해서 사용할 듯합니다.
해당 이슈로써 https://github.com/Automattic/socket.io/issues/1503 어느정도 방안에 대한 댓글을 볼수있다.
아래와 같은 것들도 있는 듯하다 아무쪼록 서비스 방향에 결정되면 좀더 연구해봐야될듯함
https://github.com/TopCloud/socketcluster
https://devcenter.heroku.com/articles/node-sessions
node.js Net 라이브러리 이용한 TCP 서버만들기
※ 자세한 내용은 아래 메뉴얼 참고
- http://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener
1. Server Code
var net = require('net'),fs = require("fs"); var sockFile = '/tmp/nodejs.sock'; var server = net.createServer(function(client) { console.log('client connected'); //client.write('hello\r\n'); //클라이언트에게 최초 접속시 데이터전달 //클라이언트에게 받은 데이터 client.on('data',function(data){ console.log('client In Data : '+data); var sendData = 'hello '+data; console.log('client Send Data : '+sendData); client.write(sendData); //클라이언트에게 추가로 데이터를 보냄 }); client.on('end', function() { console.log('client disconnected'); }); //client.on('data') 이벤트에서 client.write된 데이터와 클라이언트에서 받은 데이터해서 클라이언트에게 보냄 //client.pipe(client); }); server.on('error', function (e) { //unix sock 사용시 if (e.code == 'EADDRINUSE') { var clientSocket = new net.Socket(); // handle error trying to talk to server clientSocket.on('error', function(e) { // No other server listening if (e.code == 'ECONNREFUSED') { fs.unlinkSync(sockFile); //'listening' listener server.listen(sockFile, function() { console.log('server recovered'); }); } }); clientSocket.connect({path: sockFile}, function() { console.log('Server running, giving up...'); process.exit(); }); } }); //server.listen(sockFile, function() { //UNIX domain sockets 사용시 server.listen(8124, function() { //'listening' listener console.log('PID ['+process.pid+'] TCP Server listening'); });
2. Client Code
var net = require('net'); //var client = net.connect({path: '/tmp/nodejs.sock'},function() { // UNIX domain sockets 사용시 var client = net.connect({port: 8124},function() { //'connect' listener console.log('connected to server!'); var data = 'world!'; console.log('serve send data : '+data); client.write(data); }); //서버로 부터 받은 데이터 client.on('data', function(data) { console.log('serve get data : '+data.toString()); client.end(); }); client.on('end', function() { console.log('disconnected from server'); }); client.on('error', function(err) { console.log(err); });