기본 콘텐츠로 건너뛰기

socketcluster tutorial - 3. 기본 사용법 (Basic usage)

기본 사용법

본 튜토리얼을 진행하기 전에 '시작하기'를 읽어 보아야 합니다.

일단 SocketCluster를 설정하면 server.js라는 JavaScript 파일이 만들어집니다.
// Server code
var SocketCluster = require('socketcluster').SocketCluster;
var socketCluster = new SocketCluster({
  workers: 1,
  brokers: 1,
  port: 8000,
  appName: 'app',
  // 주요 성능 향상을 위해 wsEngine을 'uws'로 전환하세요.
  wsEngine: 'ws',
  workerController: __dirname + '/worker.js',
  brokerController: __dirname + '/broker.js',
  socketChannelLimit: 1000,
  rebootWorkerOnCrash: true
});
이러한 옵션 중 일부를 이해하려면 SocketCluster가 서버에서 3가지 다른 종류의 프로세스 클러스터로 실행되는 것을 고려해야합니다.

마스터 프로세스 (server.js)


모든 것이 시작되는 곳입니다.

Workers


이것은 모든 비즈니스 로직이 있어야하는 곳입니다 - workerController는 실시간 소켓 연결 및 이벤트를 처리하기 위해 HTTP 서버 및 실시간 SocketClusterServer에 대한 로직을 설정할 수 있습니다.

Brokers


이것은 주로 SocketCluster 내부적에서 사용하며 모든 작업자가 서로 효율적으로 이벤트를 공유 할 수 있게합니다. 또한 이 데이터를 사용하여 세션 데이터를 저장하고 여러 대의 컴퓨터에서 수평적으로 응용 프로그램을 확장 할 수도 있습니다.

보일러플레이트 앱


workerController 파일 (worker.js)을 열면 httpServer와 scServer가 요청/연결을 수락하는 코드가 보입니다. 기본적으로 httpServer는 public/folder의 내용을 제공하는 Express(정적 서버 미들웨어 포함) 모듈에 연결됩니다:
// Server code
app.use(serveStatic(__dirname + '/public'));
httpServer.on('req', app);
보일러플레이트 앱에선 scServer는 들어오는 WebSocket 연결을 처리하고 클라이언트 소켓에서 사용자 정의 'ping'이벤트를 수신합니다 (다른 것들 중에서도):
// Server code
var count = 0;
scServer.on('connection', function (socket) {
  // ...
  socket.on('ping', function (data) {
    count++;
    console.log('PING', data);
    scServer.exchange.publish('pong', count);
  });
});

여기에서 'ping'이벤트는 클라이언트 소켓이 다음을 사용하여 클라이언트에서 ping을 내보낼 때마다 트리거됩니다.
// Client code
socket.emit('ping', 'This is a PING message')
이벤트를 보내는 것은 클라이언트와 서버간에 메시지를 전달하는 가장 간단한 방법이지만 메시지를 공유하는 유일한 방법은 아닙니다.

이 목록의 예약된 이벤트 이름을 제외하고 원하는대로 이벤트의 이름을 지정할 수 있습니다. 이는 SC 내에서 특별한 의미가 있습니다. 시스템에 많은 이벤트가있는 경우, 이벤트 이름을 지정하는 좋은 규칙은 '.'기호를 사용하는 것입니다. 형식은 'myNamespace.myEvent'입니다.

채널에 데이터를 발행할 수도 있습니다. 채널에 발행하면 한 번에 여러 클라이언트에 데이터를 보낼 수 있습니다. 채널에 등록된 클라이언트는 해당 채널에 발행한 모든 데이터를 수신합니다. 클라이언트와 서버 모두 채널에 발행할 수 있습니다 (미들웨어로 인해 채널이 차단되지 않는 경우). 채널은 주로 클라이언트와 클라이언트 간의 통신을 위한 것이지만 SC는 서버의 채널을 청취하는 방법을 제공합니다 (이 주제는 다른 튜토리얼에서 더 자세한 내용을 다룹니다).

위의 서버 측 코드 조각 하나는 다음과 같이 'pong'채널에 발행하고 있습니다.

// Server code
scServer.exchange.publish('pong', count);
SocketCluster에 연결되어 있고 'pong'채널을 구독하고 있는 클라이언트는 count 변수의 값을 받습니다. 클라이언트에서 코드는 다음과 같습니다.
// Client code
// New API as of SocketCluster v1.0.0.
var pongChannel = socket.subscribe('pong');
pongChannel.watch(function (count) {
  console.log('Client received data from pong channel:', count);
});
하나 이상의 채널을 구독 취소하려면 다음 단계를 따릅니다:
// Client code
socket.unsubscribe('pong');
앞서 설명한 것처럼 scServer.exchange.publish (...)를 사용하여 서버에서 채널에 발행할 수 있습니다. 편의를 위해 SocketCluster를 사용하면 클라이언트측에서 채널에 발행할 수도 있습니다:
// Client code
socket.publish('pong', 'This PONG event comes from a client');
여기서 문자열을 인수로 전달합니다. 채널 개체에 직접 데이터를 발행할 수도 있습니다. 다음 코드는 위와 똑같은 작업을 수행합니다:
// Client code
pongChannel.publish('This PONG event comes from a client');
때로는 특정 개인의 특정 채널에 대한 읽기 또는 쓰기 권한을 제한할 수 있습니다. 이러한 목적으로 SC를 사용하려면 미들웨어 기능을 활용하세요. 이에 대해 자세히 알아 보려면 "미들웨어와 권한" 가이드를 읽어보세요.

요약


socket.emit (event, data) 함수를 사용하면 클라이언트 소켓 1 개와 일치하는 서버 소켓 1 개 (클라이언트 소켓 1 개⇄서버 소켓 1 개—클라이언트와 서버간 1대1 통신)간에 메시지를 보낼 수 있습니다.

socket.publish (event, data) 및 channel.publish (data) 함수를 사용하면 여러 클라이언트 소켓 (n 개의 클라이언트 소켓 ⇄ n 클라이언트 소켓 - 클라이언트 간의 직접 통신)을 통해 그룹 메시지를 보낼 수 있습니다. 앞에서 설명한 것처럼 교환 객체를 사용하여 서버에서 발행을 호출 할 수도 있습니다.
// Server code
scServer.exchange.publish('foo', 123);
두 클라이언트 사이의 일대일 통신을 위해 게시를 사용할 수도 있지만 두개의 승인된 클라이언트만 동일한 채널을 공유할 수 있도록 특정 미들웨어를 설정해야합니다. 자세한 내용은 "미들웨어와 권한" 가이드를 참조하십시오.

비디오 Nick Kotenberg


007 Socketcluster Server/Client Communication Basic
008 Server/Client Data 1
009 Server/Client Data 2
010 Databases and SC 101
011 Server to Server Communication

이 블로그의 인기 게시물

meteor로 nw.js 개발하기.

실제로 nw.js 어플리케이션을 개발하다보면 UI구현하기 막막하고 수동으로 리프레쉬 하는 것도 귀찮아서 Meteor 연동을 하려고 했더니 생각보다 간단했다.

디렉토리 구조는 먼저 이렇게 잡았다.
`- app
  `-client
  `-public
`- dist
  `- 배포용 html,css,js
  `- package.json
`- package.json 아이디어는 이렇다. nw.js의 시작페이지를 http://localhost:3000으로 두고 배포시엔 meteor client 배포툴인 meteor-build-client를 사용하여 html,css,js 로 분리하는 계획이다.

가장 중요한 nw.js 용 package.json 파일은 아래와 같이 구성한다.
{
  "main": "http://localhost:3000",
  "node-remote": "http://localhost:3000",
  "name": "<앱이름>"
} 이게 전부. 어떻게 보면 Web과 nw.js를 동시에 개발할 수도 있는 환경이기도 한 것이다.
meteor create app 을 해서 meteor용 앱을 만들고 meteor 를 시작한다.
그리고, 위의 package.json이 있는 경로로 돌아가서 nw . 으로 nwjs를 실행한다.

한번 번쩍하더니 잘 된다.
cordova 등에서 index.html 대신 http://localhost:3000을 하는 것도 비슷한 느낌이다.

즐겁게 개발을 일단 마구 하고 실제로 배포하기 위해서는 개발환경이 아니라 html,css,js로 구성된 배포본을 만들어야한다.
npm install -g 해도 되지만 어짜피 Meteor에서만 쓸거
meteor npm install -g meteor-build-client 해버릴거다.

개발은 문제 없어 보이고 배포판을 한번 만들어보자. meteor app 이 있는 경로(meteor run으로 …

RxJS - ReactiveX 인터뷰

A: 왜 RxJS입니까
B: javascript는 참 쉽고 친숙한 언어죠.
A: 별로 그렇게 생각 안합니다만.
B: 그래서 좀 어렵고 있어보이는게 뭘까 싶어서...
A: 네?
B: 함수형이라는게 유행하기도 하고
f(x) 좋쟎습니까? 미스테리~ 미스테리~ 정수정짱짱 으아아

이런 수학선생님이라면 수포자 따윈 A: ...
B: 그리고 반응형이라는 말 뭔가
A: 뭔가?
B: 대충대충해도 막 알아서 할거 같고...
A: 그럴리가요?
B: 안그렇겠죠?
A: 네
B: 네

(잠시만 기다려주세요)

A: 그래도 뭔가 매력이 있으니 이렇게 시간을 내셔서 이것저것 Rx에 대해 글도 쓰고 이야기도 하고 그러시는거 아닌가요?
B: 매력이라.
으음.
제가 팔꿈치 터널 증후근이 좀 있어요.
오른손 세끼손가락, 약지손가락이 저립니다.
A: 무슨 상관이?
B: 그래서 각종 괄호를 쓰는게 너무 힘듭니다.
소중대괄호 만든 사람 죽었으면.
Hello world (ASCII): https://esolangs.org/wiki/Parenthesis_Hell
A: 이미 옛날에 돌아가셨겠죠.
B: 그렇겠네요.
아무튼 그래서 소중대괄호 의존이 적은 커피스크립트를 쓰는데요.
A: 빨리 본론을 말씀해주시죠.
B: 커피스크립트에서 가로로 80자 이상쓰면 Line exceeds maximum allowed length 라고 경고해요.
A: 그래서요?
B: 근데 Rx를 쓰면 코드를 가늘게 쓸 수가 있더라구요.
A: 호오?
B: 그리고 = 쓰는 것도 너무 힘듭니다.
A: 네?
B: 오른손을 쓰쟎아요.
A: ...
그러니까 정리하면
1. 괄호가 힘들다
2. 커피를 쓴다
3. 커피는 길게 쓰면 경고
4. Rx를 쓰면 코드가 가늘다
5. 대입문을 줄이고 싶다.
B: 네
하지만 5번은 생각보다 별로...
A:
B:

B: 아!
A: ?
B: 코드가 가늘어서 좋은 점이.
A: 네.
B: 핸드폰에서 코드를 보기 좋습니다.
A: ... 왜 팔꿈치 터널 증후근이 안 낫는지 알겠습니다.
B: 도와주세요.
쇠고기 사묵으면 나을 것 같습니…

Troubleshooting - Meteor package가 적용이 되지 않을 때

버전 1.5 기준 package.js에서 Package.onUse 에 새 패키지를 추가했는데 인식하지 못하는 경우가 있다.
Package.onUse((api) => {
  api.use([
    'vulcan:core',
    'vulcan:forms',
    'vulcan:accounts' /* <-- 추가함! */
  ]);
...
} 내부패키지건 원격패키지건 안되는 안된다. 이럴 때 meteor add 후 meteor remove 해도 되지만 더 간단한 방법이 있다. meteor update vulcan:accounts 이렇게 update 해주는 방법이 있다. .meteor/package 파일을 건들지 않아서 좋다. 그래도 역시 좋지 않다. Meteor 스럽지 않다. https://github.com/meteor/meteor/issues/7721 현재 1.5.2에서도 해결이 안되었군요. 해결되어 적용되면 다시 글 올리겠습니다.