Programming/node.js2015. 2. 26. 21:15

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 


Posted by 시니^^
Programming/node.js2015. 2. 4. 11:33

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);
});


Posted by 시니^^
MobileApp/통합2015. 2. 1. 16:16

ionicframework 설치


참고 공식 홈페이지

 - http://ionicframework.com/getting-started/


1. node.js 설치 npm 필요

  다운로드 설치 : http://nodejs.org/


2. npm 실행 확인

C:\Users>npm -v 1.4.28

※ 실행 안될 경우 시스템속성->환경변수->시스템변수->PATH 에 추가함


3. cordova 설치

C:\Users>npm install -g cordova
C:\Users\admin\AppData\Roaming\npm\cordova -> 
C:\Users\admin\AppData\Roaming\npm\node_modules\cordova\bin\cordova
cordova@4.2.0 C:\Users\admin\AppData\Roaming\npm\node_modules\cordova


4. ionic 설치

C:\Users>npm install -g ionic
C:\Users\admin\AppData\Roaming\npm\ionic -> 
C:\Users\admin\AppData\Roaming\npm\node_modules\ionic\bin\ionic
ionic@1.3.3 C:\Users\admin\AppData\Roaming\npm\node_modules\ionic


5. ionic 실행해보기

C:\Users>ionic
  _             _
 (_)           (_)
  _  ___  _ __  _  ___
 | |/ _ \| '_ \| |/ __|
 | | (_) | | | | | (__
 |_|\___/|_| |_|_|\___|  CLI v1.3.3

Usage: ionic task args

=======================

※ 실행 안될 경우 npm 환경 변수 PATH 설정


6. 샘플 템플릿 프로젝트 시작

C:\Users>ionic start myApp tabs
Creating Ionic app in folder C:\Users\myApp based on tabs project
Downloading: https://github.com/driftyco/ionic-app-base/archive/master.zip
[=============================]  100%  0.0s
Downloading: https://github.com/driftyco/ionic-starter-tabs/archive/master.zip
[=============================]  100%  0.0s
Update config.xml
Initializing cordova project
Fetching plugin "org.apache.cordova.device" via plugin registry
Fetching plugin "org.apache.cordova.console" via plugin registry
Fetching plugin "com.ionic.keyboard" via plugin registry


7. 디렉토리 구조확인 www가 메인홈디렉토리, 해당안에 html / css /javascript 작업하면됨

C:\Users>cd myApp
C:\Users\myApp>dir
2015-02-01  오후 03:37    <DIR>          .
2015-02-01  오후 03:37    <DIR>          ..
2015-02-01  오후 03:37                29 .bowerrc
2015-02-01  오후 03:37               138 .gitignore
2015-02-01  오후 03:37               120 bower.json
2015-02-01  오후 03:37               798 config.xml
2015-02-01  오후 03:37             1,353 gulpfile.js
2015-02-01  오후 03:37    <DIR>          hooks
2015-02-01  오후 03:37                37 ionic.project
2015-02-01  오후 03:37               354 package.json
2015-02-01  오후 03:37    <DIR>          plugins
2015-02-01  오후 03:37    <DIR>          scss
2015-02-01  오후 03:37    <DIR>          www


8. 안드로이드 플랫폼 추가하기 확인하기

C:\Users\myApp>ionic platform add android
Running command: D:\nodejs\node.exe C:\Users\myApp\hooks\before_platform_add\ini
t_directories.js C:\Users\myApp
Creating android project...

C:\Users\myApp>dir
2015-02-01  오후 03:42    <DIR>          .
2015-02-01  오후 03:42    <DIR>          ..
2015-02-01  오후 03:37                29 .bowerrc
2015-02-01  오후 03:37               138 .gitignore
2015-02-01  오후 03:37               120 bower.json
2015-02-01  오후 03:37               798 config.xml
2015-02-01  오후 03:37             1,353 gulpfile.js
2015-02-01  오후 03:42    <DIR>          hooks
2015-02-01  오후 03:37                37 ionic.project
2015-02-01  오후 03:37               354 package.json
2015-02-01  오후 03:42    <DIR>          platforms
2015-02-01  오후 03:42    <DIR>          plugins
2015-02-01  오후 03:37    <DIR>          scss
2015-02-01  오후 03:37    <DIR>          www

C:\Users\myApp>cd platforms
C:\Users\myApp\platforms>dir
2015-02-01  오후 03:42    <DIR>          .
2015-02-01  오후 03:42    <DIR>          ..
2015-02-01  오후 03:42    <DIR>          android


9. 안드로이드 빌드 하기 

※ CordovaApp-debug.apk 확인

C:\Users\myApp>ionic build android
BUILD SUCCESSFUL
Total time: 43 seconds
Built the following apk(s):
    C:\Users\myApp\platforms\android\ant-build\CordovaApp-debug.apk

C:\Users\myApp>cd platforms\android\ant-build\
C:\Users\myApp\platforms\android\ant-build>dir
2015-02-01  오후 03:47    <DIR>          .
2015-02-01  오후 03:47    <DIR>          ..
2015-02-01  오후 03:47             1,266 AndroidManifest.cordova.xml
2015-02-01  오후 03:47               124 AndroidManifest.xml.d
2015-02-01  오후 03:47               189 build.prop
2015-02-01  오후 03:47    <DIR>          classes
2015-02-01  오후 03:47           404,956 classes.dex
2015-02-01  오후 03:47             1,327 classes.dex.d
2015-02-01  오후 03:47         3,404,475 CordovaApp-debug-unaligned.apk
2015-02-01  오후 03:47               267 CordovaApp-debug-unaligned.apk.d
2015-02-01  오후 03:47         3,404,491 CordovaApp-debug.apk
2015-02-01  오후 03:47         3,246,481 CordovaApp.ap_
2015-02-01  오후 03:47             6,287 CordovaApp.ap_.d
2015-02-01  오후 03:47    <DIR>          dexedLibs
2015-02-01  오후 03:47               115 proguard.txt
2015-02-01  오후 03:47               195 R.txt
2015-02-01  오후 03:47    <DIR>          res

10. 안드로이드 앱 실행해보기

 1) 에뮬레이터로 실행하기

C:\Users\myApp>ionic emulate android

  ※ 안드로이드 SDK 설치되어 있어야하며 AVD(Android Virtual Device) Manager 로 설정 되어있어야함   

    - http://developer.android.com/sdk/installing/index.html?pkg=tools


 2) USB 연결되어 있는 상태에서 스마트폰 개발자모드에서 바로 실행

C:\Users\myApp>ionic run android

 ※ 개발자모드 enable 

   설정 -> 스마트폰정보(태블릿정보) -> 빌드번호 여러번 클릭하면됨 메시지뜸(아래 링크참고)

  - http://www.greenbot.com/article/2457986/how-to-enable-developer-options-on-your-android-phone-or-tablet.html

  - http://www.androidcentral.com/how-enable-developer-settings-android-42

 ※ Google USB Driver selected 설치 되어있어야 하며 추가로 장치관리자에서 연결된 Android 기계 Driver 업데이트 해줘야됨

   - http://delphi.org/2014/01/custom-android-adb-usb/


 3) Apk파일 안드로이드에 넣어서 apk Install 로 설치해도됨


11. 웹소스 수정이로 인한 매번 빌드해서 디버깅하는 시간 단축하기 위해서 가상서버 실행

 ※ 브라우져로 http://localhost:8100 에서 확인가능

C:\Users\myApp>ionic serve
Running dev server: http://localhost:8100
Running live reload server: http://localhost:35729
Watching : [ 'www/**/*', '!www/lib/**/*' ]
Ionic server commands, enter:
  restart or r to restart the client app from the root
  goto or g and a url to have the app navigate to the given url
  consolelogs or c to enable/disable console log output
  serverlogs or s to enable/disable server log output
  quit or q to shutdown the server and exit


Posted by 시니^^