기본 콘텐츠로 건너뛰기

2016의 게시물 표시

socketcluster tutorial - 11. 성능 (Performance)

성능 벤치 마크 처리량 (SocketCluster v0.9.8) 이 테스트의 목적은 SocketCluster가 적절한 머신에서 얼마나 많은 JavaScript (JSON) 객체를 처리할 수 있는지를 보는 것이었습니다. 절차 이 CPU 벤치 마크에서 SocketCluster는 Linux를 실행하는 8 코어 Amazon EC2 m3.2xlarge 인스턴스에서 테스트하였습니다. 100 명의 동시 클라이언트가 있을 때까지 매 초마다 새로운 클라이언트를 생성하였습니다. 전송한 최대 메시지 수는 170k (클라이언트 당 초당 1700 개의 메시지)로 설정하였습니다. 메시지는 완전히 양방향이었습니다 - 클라이언트는 JSON으로 캐스팅 된 JavaScript 객체를 포함하는 'ping'이벤트를 보내고 서버는 'pong'JavaScript 객체로 응답합니다. 이 객체에는 현재 워커가 지금까지 받은 총 ping의 수를 나타내는 'count'속성이 있습니다. SocketCluster는 5 개의 로드 밸런서, 5 명의 워커 및 2 명의 브로커를 사용하도록 설정하였습니다. 관측 로드 밸런서 모듈을 v0.9.12로 업그레이드하면 워커 간에 훨씬 더 균등한 분배가 이루어졌습니다. 이전 버전의 loadbalancer는 갑작스러운 트래픽 급증에도 반응이 없었습니다. 새로운 버전의 loadbalancer는 무작위 확률을 결정론적 '불운'보정으로 활용하는 알고리즘을 사용하여 부하가 워커 간에 균등하게 분산되도록 합니다. 프로세스 설정은 이전 벤치 마크에서 제대로 조정되지 않았습니다. CPU 코어보다 많은 프로세스를 사용하는 것은 낭비입니다. 더 적은 수의 프로세스를 사용하여 매우 양호한 부하로 평균 3.33을 만들었습니다 (가능한 8 개 중). 아마도 우리의 현재 설정으로 20만 개의 접속이 되도록 했을 것입니다. 로드 밸런서 5대, 워커 5개, 브로커 2개가 여전히 이상적이진 않습니다

socketcluster tutorial - 6. 미들웨어 및 인증 (Middleware and authorization)

미들웨어 및 인증 SocketCluster를 사용하면 클라이언트는 JavaScript를 사용하여 특정 채널로 데이터를 청취하고 발행하여 메시지를 서로 공유할 수 있습니다. 기본적으로 누구나 자신이 좋아하는 채널에 데이터에 수신하고 게시할 수 있습니다. 일부 시스템에서는 이것이 문제가 되지 않지만 대부분의 시스템은 사용자가 서로 상호 작용할 수 있는 방법을 규제하기 위해 어느 정도의 접근 제어가 필요합니다. 대부분의 시스템은 적절한 접근 권한을 시행하기 위해 연결을 인증하고 권한을 부여하는 방법이 필요합니다. 미들웨어 기능은 이러한 모든 작업을 수행할 수 있는 깔끔한 중앙 집중식 방식을 제공합니다. SocketCluster에서 모든 실시간 이벤트는 서버에서 처리하기 전에 미들웨어 기능을 통과해야 합니다. SocketCluster는 다양한 종류의 상호 작용을 처리할 수 있는 다양한 종류의 미들웨어 라인을 제공합니다. 가장 유용한 미들웨어 라인은 워커 프로세스에 있지만 로드 밸런서(HTTP 용)에 의해 노출되는 미들웨어 라인이 있습니다. 이 튜토리얼에선 워커(실시간) 미들웨어에만 초점을 맞춥니다. 워커는 실시간 scServer 객체를 통해 미들웨어를 노출합니다. 이 객체는 worker.getSCServer() 를 사용하여 액세스 할 수 있습니다. 미들웨어 기능을 서버에 추가하려면 다음을 사용해야 합니다. scServer.addMiddleware (middlewareType, middlewareFunction); scServer에서 사용할 수있는 미들웨어 유형은 다음과 같습니다. scServer.MIDDLEWARE_HANDSHAKE scServer.MIDDLEWARE_SUBSCRIBE scServer.MIDDLEWARE_PUBLISH_IN scServer.MIDDLEWARE_PUBLISH_OUT scServer.MIDDLEWARE_EMIT middlewareFunction에 전달한 req인자는 사용한 미들웨어의 종류에 따라 다릅니다.

socketcluster tutorial - 10. 복수 호스트 확장 (Scaling across multiple hosts)

복수 호스트 확장 SocketCluster를 사용하면 수직적(시스템/호스트의 여러 CPU 코어에 걸쳐)으로 수평적으로(여러 호스트에 걸쳐) 확장할 수 있습니다. 수평으로 확장하려면 SCC(권장)를 사용하거나 처음부터 직접 솔루션을 구현할 수 있습니다. SCC를 사용하는 경우 SC가 시스템에서 채널 데이터를 동기화하는 방법에 대한 구현 세부 정보를 배울 필요가 없습니다. SCC SCC는 2016 년 9 월에 도입되었습니다. SC는 여러 호스트에서 SC를 확장하기 위한 컴포넌트 모음입니다. SCC는 설치가 쉬우며 뒤에서 일어나는 일에 대해 많이 알 필요 없이 수평적 확장성을 제공합니다. Kubernetes위에 SCC를 실행하면 위아래로 스케일 업이 자동으로 처리됩니다. SCC 사용에 대한 전체 안내서는 여기 에 있습니다. SCC를 사용하는 경우 '수동으로 크기 조정'에 대한 아래 섹션을 읽을 필요가 없습니다. 수동으로 크기 조정 수평적 확장의 목표는 최적의 방법으로 트래픽을 모든 사용 가능한 시스템에 분산하는 것입니다. SocketCluster의 컨텍스트에서 수평 확장은 두 가지 특정 문제로 귀결됩니다. 들어오는 클라이언트 연결을 보낼 호스트를 어떻게 선택합니까? 한 클라이언트가 채널에 데이터를 게시할 때 다른 호스트의 해당 채널에 가입 한 다른 클라이언트가 채널 데이터를 실시간으로 수신하는지 어떻게 확인할 수 있습니까? 첫 번째 과제에 접근하는 데는 여러 가지 방법이 있습니다. 예를 들면 다음과 같습니다. 무작위로 호스트 URL을 선택하고 클라이언트 소켓의 connect() 메서드에 옵션으로 전달하여 각 클라이언트를 호스트 중 하나에 직접 보낼 수 있습니다. 로드 밸런서를 사용하여 들어오는 연결을 대상 호스트에 고르게 분산할 수 있습니다. 타사 서비스를 사용할 수도 있고 직접 설정할 수도 있습니다. SocketCuster v1.xx를 사용하는 경우 sticky로드 밸런서(예 : IP 주소 기반의 Sticky)

socketcluster tutorial - 9. SSL을 적용한 상용 서비스 운영(Running in production (with SSL))

SSL을 적용한 상용 서비스 운영 SocketCluster에 시스템을 구축할 때 마스터 프로세스(server.js)에 런타임 구현을 배치하지 않는 것이 중요합니다. 이러한 구현은 worker(worker.js) 내부에 배치하는 것이 좋습니다. 마스터 프로세스와 달리 워커는 충돌할 때마다 (오류가 발생하지 않는 경우) 자동으로 재발행하고 서비스 중단을 최소화됩니다. 일반적으로 워커는 재발생하는데 1 초 미만이 걸리므로 사용자에게 투명해야 합니다. 마스터 프로세스는 일반적으로 초기 실행 구현을 넣고 장시간 실행되는 데몬 프로세스를 생성하기에 좋은 곳이지만 일단 시스템이 실행되면 오류가 발생하기 쉬운 논리를 실행하는데 이 프로세스를 사용하지 않아야합니다. 이러한 규칙을 따르는 경우 Node 명령을 사용하여 직접 SocketCluster 서버를 실행하면 실제 운영 환경에서 정상적으로 작동합니다. (인수 포함 예제). nohup node server.js -w 2 -s 2 & 안심할 수 있도록 master를 자동으로 재생성하려면 forever를 사용하십시오. npm install -g forever 설치한 후 다음과 같이 실행하십시오. forever start --killSignal=SIGTERM server.js -w 2 -s 2 어떤 경우든 서버 기반 코드를 강제로 업데이트하기 위해 거의 다운타임 없는 배포를 수행하는 경우 마스터 프로세스에 SIGUSR2 신호를 보낼 수 있습니다. 자세한 내용은 이 문제 를 참조하십시오. SSL 프로덕션 환경에서 SC를 실행할 때 고려해야 할 또 다른 중요한 점은 일부 오래된 프록시가 WebSocket 트래픽을 차단할 수 있다는 것입니다. 이 문제를 방지하려면 SC 인스턴스에 키/인증서 SSL쌍을 제공하여 HTTPS/WSS를 통해 앱을 제공해야합니다. SSL/TLS를 사용하도록 SC를 구성하려면 부팅 옵션 을 설정해야합니다. '프로토콜'을 'https'로 설정하

socketcluster tutorial - 8. SocketCluster로 풀스택 발행/구독 (Full stack pub/sub with SocketCluster)

SocketCluster 풀스택 펍섭(발행/구독) Socket.io 스타일의 emit/on 기능 외에도 SocketCluster를 사용하면 JavaScript(NodeJS 서버)를 사용하여 클라이언트 또는 서버의 실시간 pub/sub 채널과 상호 작용할 수 있습니다. 미들웨어 기능을 정의함으로써 SC는 실시간 데이터를 완벽하게 제어 할 수 있습니다. 미들웨어는 클라이언트가 특정 채널을 구독하고 게시하는 것을 차단하는 데 사용할 수 있지만 다른 클라이언트에 도달하기 전에 실시간 스트림을 백엔드로 변환하는데도 사용할 수 있습니다. 이 다이어그램은 SC v1.x.x의 아키텍처를 나타냅니다. SC v2.0.0+는 고정 로드 밸런서 계층(sticky load balancer layer)이 없습니다. 대신 워커는 동일한 포트를 공유하고 어느 포트가 가장 바쁜지를 기준으로 새로운 연결을 선택합니다. 다이어그램은 조금 일반적이지만 채널 1, 채널 2, 채널 3 ...은 고객이 참여할 수있는 다양한 대화방입니다. 각 방은 '수학', '물리학' , '화학'...과 같은 특정 ​​주제를에 집중할 수 있습니다, '물리학'방에 게시한 모든 메시지를 듣기 위해서는 클라이언트에서 다음과 같이 해야 합니다. // SocketCluster API v1.0.0 var physChannel = socket.subscribe('physics'); physChannel.watch(function (data) {...}); 물리학 방에 메시지를 전달하기 위해선 다음과 같이 호출합니다: socket.publish('physics', messageData); ... 혹은 physChannel.publish(messageData); 여러 사용자가 채널을 공유 할 필요는 없습니다. 개별 사용자를 위해 채널을 설정할 수 있습니다. 예를 들어 사용자 이름이 'bob123'인 사용

socketcluster tutorial - 7. 실패 처리 (Handling failure)

실패 처리 프로덕션의 실시스템은 시스템 실패를 처리 할 수 있어야합니다. 고려해야 할 가장 일반적인 실패 원인 중 하나는 연결 불량에 대한 가능성입니다. SC의 이벤트 관련 메소드는 서버가 액션을 확인할 때 '콜백'함수를 최종 인수로 사용합니다. 메서드가 실패하면 콜백은 인수로 오류를 받습니다.이 경우 메서드 호출을 다시 시도하거나 사용자에게 메시지를 표시하여 문제를 알릴 수 있습니다. 다양한 오류를 처리하는 방법은 다음과 같습니다. (샘플 코드) Client측 보내기 // Client code socket.emit('ping', 'This is a ping', function (err) {   if (err) {     // 보내기 이벤트 실패, 재시도 혹은 사용자에게 계속할지 여부를 물어봄.   } else {     // 보내기 이벤트 성공   } }); 콜백 인수를 전달하지 않으면 emit 메소드가 실패하지 않습니다. 이 경우 emit 호출은 이벤트를 중요도 낮음 (휘발성)으로 처리합니다. 이 기능은 초당 여러 번 이벤트를 내보내고 가끔 실패하는 경우 신경 쓰지 않는 경우에 유용합니다. emit 메소드에 콜백을 전달하면 상대에게 명시적으로 응답을 보내야 합니다. (그렇지 않으면 콜백이 시간 초과됩니다): // Server code socket.on('ping', function (data, res) {   // ...   if (success) {     res(null, 'Success'); // 성공 메시지 돌려주기   } else {     res('Error message'); // 오류 반환   } }); res 함수의 첫 번째 인수는 오류(모든 JSON 호환 타입 또는 객체)입니다. 일반 메시지(오류 없음)를 보낼  경우 첫 번째 인수를 null로 해야합니다. 원하는 경우: res (123, '

socketcluster tutorial - 5. 인증 (Authentication)

인증 개요 v1.3.0 이전에는 SocketCluster의 인증이 세션을 중심으로 돌아갔습니다. v1.3.0부터 인증은 JSON 웹 토큰 (JWT)을 기반으로합니다. SC의 인증 토큰 시스템은 다음 문제를 해결하도록 설계되었습니다. 사용자가 자격 증명을 다시 입력할 필요없이 연결이 끊어진 상태를 복구한 후 로그인 상태를 유지할 수 있습니다. 하나만 사용하여 로그인하면 열려있는 모든 브라우저 탭에서 사용자를 인증 할 수 있습니다. (여러 브라우저 탭간에 인증 토큰 공유). SC의 인증 시스템에 대한 중요한 설계 고려 사항은 작업해야하지만 특정 데이터베이스 엔진이나 기본 데이터 (사용자 계정 정보 포함)와 완전히 독립적이어야한다는 것입니다. 이를 달성하기 위해 SC는 JWT 인증 토큰의 개념을 도입해야했습니다. 간단히 말해서, 인증 토큰은 서버에서 비밀 authKey로 서명하고 인증 (로그인) 프로세스의 일부로 클라이언트에 전송하는 사용자 정의 Object/JSON입니다 (SocketCluster 생성자의 authKey 옵션은 여기 참조). 토큰의 데이터는 클라이언트에 제공할 때 서명하므로 토큰을 무효화하지 않고 토큰을 수정할 수 없습니다. 즉, 서버 소켓에 유효한 auth 토큰이 첨부되어 있으면 ( socket.authToken 참조) 클라이언트의 토큰이 서버에 의해 서명되었으므로 서버의 데이터가 유효하다는 것을 알 수 있습니다. 인증 토큰에 대해 주의해야 할 중요한 사항 중 하나는 클라이언트가 성공적으로 인증 된 이후 에 클라이언트에 제공해야하며 클라이언트와 서버 사이에 비밀로 유지되어야합니다 (다른 클라이언트와 공유되지 않음). SC의 인증 토큰은 특정 사용자와 관련된 모든 종류의 액세스 제어 정보를 저장하는 데 사용할 수 있습니다. 일반적으로 사용자 이름 데이터만 포함하는 간단한 토큰을 만드는 것으로 충분합니다: {   username: 'bob123' } 인증 절차 SC에서 인증을 구현하는 올바른 방법

socketcluster tutorial - 4. 디버깅 (Debugging)

디버깅 일반적인 NodeJS 프로세스를 디버그하는 것과 거의 같은 방법으로 SC 프로세스를 디버그 할 수 있습니다. 유일한 차이점은 SC에는 다양한 방식으로 서로 상호 작용하는 여러 종류의 프로세스가 있기 때문에 일반적으로 동시에 모두를 디버그하는 일은 없습니다. 이러한 이유로 SC에서는 --debug-workers 및 --debug-brokers CLI 인수를 제공하여 워커와 브로커를 각각 디버그 할 수 있습니다. Node.js 버전 6.3.0 이상을 사용하는 경우 --inspect-workers 및 --inspect-broker 를 사용하면 외부 디버거를 실행할 필요가 없습니다. 저, Node.js v0.11.0 + (가장 최근의 안정 버전)을 사용하고 있는지 확인하십시오. Node-inspector를 전역으로 설치하십시오 (Node.js v6.3.0 이상인 경우 이 단계를 건너 뜁니다). npm install -g node-inspector 그런 다음 콘솔 창에서 다음을 사용하여 실행하십시오: node-inspector ^ 전체 디버깅 세션에 걸쳐 이 콘솔을 자체 콘솔 (또는 백그라운드)에서 실행해야합니다 (개별 디버그 사이에서 다시 시작할 필요가 없습니다). 디버깅을 시작하려면 새로운 콘솔을 열어야합니다. Node를 사용하여 server.js 파일을 실행할 때 --debug-workers , --debug-broker , --inspect-workers 또는 --inspect-brokers 인수를 전달해야합니다. 서버 파일 이름 뒤 에 플래그를 추가하십시오. 그렇지 않으면 작동하지 않습니다. 예를 들면 node server --debug-workers 혹은 node server --debug-brokers 또는 (Node.js version >= 6.3.0) node server --inspect-workers 또는 (Node.js version >= 6.3.0) node server

탄력받은 김에 socketcluster 호스팅 서비스인 baasil.io 도 써보았다.

한달 무료 플랜이 있어서 광속가입. 나는야 시스템 어드민이기 때문에 유저따윈 얼마든지 만들 수 있다. 철자가 좀 헷깔린다. baasil.io 다. 다소 웹페이지가 엉성한 느낌은 있다. 이런건 망하기 전에 잽싸게 빨대 꽂는 것이 인지상정. 아마도 대부분 유료를 겁내고 자신의 계정이 한달짜리 트라이얼로 소모되는게 아까우실거라고 생각하여 대신 가입해봄 -_-)v 가입 후 Email validation을 하고 나면 어서와. 소켓클러스터는 처음이지? 매우매우매우 심플하다. Baasil.io manages your real-time infrastructure for you without compromising on flexibility. We provide you with a highly scalable, open source boilerplate (SCC) which you can modify as you like and then deploy to your own Kubernetes environment/cluster using a single command. The boilerplate we provide is designed to scale seamlessly across up to 1000 machines/hosts. For the standard plan, Baasil.io gives you an isolated environment on a shared Rancher control panel. This setup is ideal if you have a relatively small number of machines (e.g. 1 to 20 hosts in your cluster) and are happy to look after your cluster using Rancher. If you would like to support more than 20 machines, want a completely hands-off experi

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 내부적에서 사용하며 모든 작업자가 서로 효율적으로 이벤트를 공유 할 수 있게합니다. 또한 이 데이터를 사용하여 세션 데이터를 저장하고 여러 대의 컴퓨터에서 수평적으로 응용 프로그램을 확장 할 수도 있습니다. 보일러플레이트 앱 workerContr

socketcluster tutorial - 2. 시작하기 (Getting Started)

시작하기 SocketCluster를 시작하려면 Node.js 가 설치되어 있어야 합니다. 이 지침 에 따라 NodeJS를 설치할 수 있습니다. 또는 Baasil.io 로 Docker 컨테이너에서 SocketCluster를 실행할 수 있습니다. - Kubernetes 환경에 앱을 배포하려는 경우 이상적입니다 - 여기 를 참조하십시오. Node가 설치되면 SocketCluster를 설치할 수 있습니다. SocketCluster를 설치하는 두 가지 방법이 있습니다. 가장 간단한 방법 프레임워크로 설치할 수 있고 보다 구체적인 요구 사항이있는 경우 클라이언트와 서버를 따로 설치할 수도 있습니다. 두 설정은 거의 동일한 API를 공유하므로 일반적으로 전환할 때 코드를 변경할 필요가 없습니다. 사실, socketcluster-server는 socketcluster (프레임 워크)의 직접적으로 종속됩니다. SocketCluster를 독립 실행형 서버 및 클라이언트로 설치하려면 다음을 수행하십시오. 여기(서버) 와 여기(클라이언트) 의 지침을 따르십시오. 프레임워크로 설치하려면 (권장) : npm install -g socketcluster 일단 설치되면, socketcluster create 명령은 새로운 SocketCluster 를 설치합니다. 예를 들어, socketcluster create myApp 는 현재 작업 디렉토리에 myApp 라는 디렉토리를 작성합니다. socketcluster create myApp 번들된 패키지(webpack같은)에서 사용하려면 npm install --save socketcluster npm install --save socketcluster-client 하고 서버에서 var SocketCluster = require('socketcluster').SocketCluster 그리고 클라이언트에서 var SocketCluster = require('socketcl

socketcluster tutorial - 1. 소개 Introduction

소개 SocketCluster는 빠르고 확장성이 뛰어난 HTTP + WebSockets 서버 환경으로, 시스템/인스턴스의 모든 CPU 코어를 사용하는 다중 프로세스 실시간 시스템을 구축할 수 있습니다. Node.js 서버를 단일 스레드로 실행해야하는 한계를 없애고 worker 충돌에서 자동으로 복구하여 백엔드를 복원합니며. 오류도 중앙 로그로 모아줍니다. SocketCluster는 Docker 컨테이너의 Kubernetes에서 실행되도록 최적화되어 있습니다 (자세한 내용은 SCC 참조). SocketCluster는 pub/sub시스템(브라우저 / IoT 장치까지)과 같이 작동합니다. - 실제로 필요한 특정 이벤트를 클라이언트에게 전달합니다. SC는 수직으로 (프로세스의 클러스터로서) 수평적으로 (여러 머신 / 인스턴스) 모두 확장 할 수 있도록 설계하였습니다. SC는 모듈 구조로 설계하였으므로 express와 같은 다른 프레임 워크 위(또는 자신 만의 빌드!)에서 동작가능합니다. SC의 실시간 API는 Socket.io의 API와 비슷합니다. SocketCluster를 독립형 프레임 워크(HTTP 및 WebSocket 서버로 작동)로 사용하거나 실시간 엔진으로 만 사용하고 클라이언트 스크립트를 별도로 제공할 수 있습니다. http://npmjs.org/socketcluster-client 를 참조하십시오. Twitter 를 팔로우하세요. http://socketcluster.launchrock.com/  에서 업데이트를 구독하세요. 이 사이트는 오픈 소스이기도 하며 Github 참여를 환영합니다. 게임에서 SC는 멀티 플레이어 온라인 게임 제작에 이상적입니다. Phaser 데모 를 보십시오. 대역폭 소비를 줄이려면 sc-codec-min-bin 과 함께 SC를 사용하는 것이 좋습니다. 이 코덱은 SC 메시지를 압축하여 유선을 통해 전송 될 때 이진 패킷으로 변환합니다. 또는 특정 게임/응용 프로그램에 최적화 된 자신만의

socketcluster 를 써보았다. 아주 좋았다.

일단 worker.js에   scServer.on('connection', function (client) {     console.log(`${client.id} is connected`);   }); 그리고 client쪽은 var socket = socketCluster.connect(); socket.on('error', function (err) {   throw 'Socket error - ' + err; }); socket.on('connect', function () {   console.log('CONNECTED'); }); 이쯤에서 시작해보자. 클라이언트가 시작하면 서버쪽에선 client.id 가 발급되는 것을 볼 수 있다. QVmNv2hblXhynoXOAAAE is connected 아마 이런 식으로 응답할 것이다. DDP처럼 RPC 와 Pub/Sub을 해보자. 먼저 단순 호출+응답 형태를 구현해보자. 서버는 socket.on('connect', ...); 가 다음에 이렇게      socket.on('message.send', function (data) {       console.log(data);     }); 클라이언트에선 그저 크롬 창 열고 socket.emit('message.send', { message: 'PING' }); 해보자. 서버쪽에서 PING 찍히면 오케이. 이 메시지를 Pub/Sub으로 해보자. 서버쪽 구현을 변경하자.     socket.on('message.send', function (data) {       console.log('message.send', data);       scServer.exchange.publish('message.pub

Chrome source map 먼지팁 (coffeescript/typescript/babel)

잘 되다가 갑자기 coffeescript/typescript/babel 등등의 디버깅이 sourcemap 연결 안된다면 크롬 디버거 열고 F1 누르고 Settings > Preferences > Sources > Enable Javascript source maps 를 체크해준다. 그러고 다시 크롬 디버거를 열어보면 Sources 탭에 요렇게 예쁘게 나온다. 갑자기 설정이 풀렸다 싶으면 당황하지 말고 Settings를 확인해보자.

tutorial - radio button을 이용한 tree 구조 만들기

http://jsbin.com/cikuga/edit?html,css,output IE 호환을 위해 jQuery를 사용했다. 안해도 되지만 이 편이 그래도 좀 읽기 쉽지 않나 싶다. 접히고 펼쳐지는 트리구조를 만드는 데 있어 핵심 아이디어는 같은 깊이에 인접한(sibling ) 요소들끼리는 radio button을 사용하면 된다는 것이다. 가령 <input type="radio" name="group1"> <input type="radio" name="group1"> <input type="radio" name="group1"> 이렇게 했을 경우 같은 이름(name)을 가지고 있으므로 셋 중 하나만 radio 버튼이 들어오고 <input type="radio" name="group1"> <input type="radio" name="group2"> <input type="radio" name="group2"> <input type="radio" name="group2"> <input type="radio" name="group1"> <input type="radio" name="group1"> 이와 같이 구성하면 group2는 group2끼리 group1은 group1끼리 각각 구성할 수 있다. 따라서 각각의 radio button에 대한 id가 1   1-1   1-2 2   2-1     2-1-1     2-1-2 3 일 경우엔 1,2,3을 top 1-1, 1-2는 1 2-1은 2

Meteor DDP subscribe 처리 시 주의할 점

Meteor에서 logout 시 독특한 패턴으로 websocket이 날아오기 때문에 주의해야한다. 먼저 logout을 보내면 ["{\"msg\":\"method\",\"method\":\"logout\",\"params\":[],\"id\":\"3\"}"] 가입 되있던 모든 publish에 영향 받는 collection이 removed 된다. a["{\"msg\":\"removed\",\"collection\":\"users\",\"id\":\"ySWmTt329QeLQZTEc\"}"] 80 23:56:26.494 ......... a["{\"msg\":\"ready\",\"subs\":[\"CPSzK3DsirQq4fSmo\",\"87ojrAZZKFwu9LTeH\",\"5ynAG9oTZg7i3DMCs\",\"KZBaQRzyPiF33BoLz\",\"w3JwjFeWaFmxXiiaL\",\"ZM9oXYRjZ7cfSxvMY\",\"Q7XAmPJC35NjLdBYL\"]}"] 189 23:56:26.529 정체불명의 subs 가 array로 뭉텅 날아오고 a["{\"msg\":\"updated\",\"methods\":[\"3\"]}"] 46 23:56:26.530 logout method 에 대한 updated 와 a["{\"msg\":\"res

decaffeinate hack - Rx.js 를 import 해보자!

http://decaffeinate-project.org/repl 평소에 coffee를 좋아하지만 ecma6로 바꿔서 보여줘야 좋아하는 분들이 종종 있어서 decaffeinate를 쓰다보니 나름 console.log 만 띡 나오는게 꽤 쓰기 좋아서 자주 쓰는데. 쓰다보니 아쉬운 점이 외부 라이브러리를 불러올 수가 없어서 약간의 hack을 해보기로 했다. script = document.createElement('script') script.src = "//cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.0-rc.2/Rx.js" x=document.getElementsByTagName('script')[0] x.parentNode.insertBefore script, x 단순하게 생각하면 이런 식 script tag을 하나 만들고 src를 Rx.js CDN 라이브러리로 지정하고 insertBefore를 사용해서 밀어넣으면 될거라고 생각했는데 repl.js?t=2015-03-09T08:30:22-07:00:7 Uncaught Error: module is not supported in the browser, you need a commonjs environment such as node.js/io.js, browserify/webpack etc 이런 오류가 난다. 보니까 의도적으로 decaffeinate에서 "module", "exports", "require" 이라는 말을 쓰면 저지하도록 되있더라   ["module", "exports", "require"].forEach(function(commonVar){     Object.defineProperty(window, commonVar, {       get: function () {         throw n

Bluestacks OS X를 android 개발용으로 쓰는 법

먼저 docker 를 설치했다면 꺼준다. 둘 다 가상화를 쓰는 시스템이라 충돌한다. vi ~/Library/Preferences/com.BlueStacks.AppPlayer.plist 로 들어가서 width 와 height 부분을 바꿔준다. <key>Width</key> <integer>420</integer> <key>Height</key> <integer>700</integer> 420x700 으로 바꾸면 720p 노트북에서 그럭저럭 볼만하다.

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: 핸드폰에서 코드를 보기 좋습

RxJS 에서 requestAnimationFrame 을 사용하려면?

http://jsbin.com/qosigic/edit?html,js,output 소스는 이쪽. 게임과 같은 분야는 타이밍 처리가 매우 중요하기 때문에 UI를 갱신하는 무한 루프를 놓고 delta 시간을 얻어와서 처리하는 로직을 많이 쓰는데 이걸 Javascript 에서 할 땐 전통적으로 setTimeout 을 걸어놓은 함수를 재귀하는 식으로 썼는데 문제는 setTimeout(setInterval도 마찬가지)이 굉장히 부정확한 타이밍을 가지고 있었고 이를 보완하기 위해 requestAnimationFrame 이라는 것을 만들어 사용하기 시작했다. 문제는 역시 지원하지 않는 몇몇 브라우저(ex. IE < 10)들 때문에 안타깝게도 RxJS 5.x 의 defaultScheduler에선 setTimeout( https://github.com/Reactive-Extensions/RxJS/blob/6dac0365ad22f87a92197fc4dcee70e72a11ddbb/src/modular/scheduler/defaultscheduler.js#L119 )을 쓰고 있는데 물론 권장하는 방식은  https://github.com/Reactive-Extensions/RxJS/tree/8fa95ac884181fb6cbff8ce7c1d669ffb190f5e4/examples/crop  의 예처럼 RequestAnimationFrameScheduler 를 사용하는 것이지만 RxLua 처럼 기본으로 타이머가 없고 외부패키지에 의존하는 환경도 있고해서 기본 RxJS 환경에서 직접 만들어보기로 했다. Scope 을 위해 일단 function으로 감싸보았다. (function() {   var canvas=document.getElementById('canvas1');   var ctx = canvas.getContext('2d');   var start = 0;   var step = function(timestamp)

RxJS Basic - 기초

http://reactivex.io/rxjs/manual/tutorial.html  글을 대충 번역해서 쓰는 글입니다. jsbin/codepen 같은 곳에서 RxJS 라이브러리를 추가한 후 연습해봅시다. 현재 가장 최근 버전은  https://cdnjs.com/libraries/rxjs/5.0.0-rc.1  에서 확인하세요. Observable 로 변환하기 하나 혹은 n 개의 값으로부터 Rx.Observable.of('foo', 'bar'); =>foo =>bar 배열로부터 Rx.Observable.from([1,2,3]); =>1 =>2 =>3 이벤트로부터 Rx.Observable.fromEvent(document.querySelector('button'), 'click'); =>button을 누를 때 마다 event로 변환 Promise로부터 Rx.Observable.fromPromise(fetch('/users')); =>/user 주소의 내용을 fetch한 것을 변환 마지막 인자가 콜백인 경우 콜백으로부터 /* node.js */ var exists = Rx.Observable.bindCallback(fs.exists); exists('file.txt').subscribe(exists => console.log('Does file exist?', exists)); var rename = Rx.Observable.bindNodeCallback(fs.rename); rename('file.txt', 'else.txt').subscribe(() => console.log('Renamed!')); Observable 만들기 외부로부터 새로운 이벤트를 생성한다. var myObservable = Rx.Subject.create(); myObserv

JavascriptCore in Swift 3 연습

//: Playground - noun: a place where people can play import UIKit import JavaScriptCore /* swift to javascript */ let str = "var double=function(x) { return x*2 };" let context = JSContext () context ?. evaluateScript ( str ) let getDouble = context ?. objectForKeyedSubscript ( "double" ) getDouble ?. call (withArguments: [ 1 ]). toString () *2를 하는 double이라는 function을 js에서 만들고 swift에서 인지 1을 넣어 2를 반환하는 예. 스위프트에서 자바스크립트 함수를 호출할 때는  objectForKeyedSubscript를 사용하여 함수명을 지정하고 call(withArguments: [, ... ]) 를 사용하여 인자를 지정한다. 결과값은 JSValue 형이므로 적당히 변환해서 사용한다. /* javascript to swfit */ let str2 = "postMessage('갔다가 다시 올꺼야')" let postMessageBlock : @convention(block) (AnyObject?) -> (AnyObject) = { (data) in     print(data)     return data! } context?.globalObject.setValue(unsafeBitCast(postMessageBlock, to: AnyObject.self), forProperty: "postMessage") context?.evaluateScript(str2) 반대의 경