=================================
=================================
=================================
출처: http://nerobong2.blogspot.com/2017/01/nodejs-nodejs.html
nodejs란? 자바스크립트 기반 서버 사이드 스크립트 언어
설치방법은 따로 블로그 하지 않겟다.(매우간단함.)
설치완료 하면 node_modules 라는 폴더가 생성되고 기본 내장 js 모듈 파일들이 존재하며
require 키워드를 통해 어디서든 사용가능 하다.
단 라이브러리를 추가할때는 node_modules 폴더가 존재하는 위치에서 mpn ~~ 을 실행하길 추천한다.
테스트 os 는 윈도우 실제 적용환경은 리눅스(centOS) 였음.
아래 코드는 각각의 OS 에서 정상작동한다.
서버코드.
//websocket 객체 생성 (npm 으로 라이브러리를 추가해야한다.)
var WebSocketServer = require('websocket').server;
//http 객체 생성
var http = require('http');
//nodejs 는 스크립트 오류가 발생시 프로세스가 종료된다. 따라서 예외처리는 필수
try{
//http 객체로부터 서버를 생성한다.
var server = http.createServer(function (req, res) {
//이부분은 알아서~변경
res.writeHead(404);
res.end();
});
//서버포트를 설정한다. 8887번포트 리슨대기 상태
server.listen(8887, function () {
});
//websocket 웹소캣 객체생성자에 위에서 생성한 server 객체를 httpServer
//값에 셋팅 한다.
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
//웹소캣 이벤트 정의
wsServer.on('request', function (request) {
//이부분에서 좀 해맷다. CP의 폐해
//accept 함수 첫번째 인자 값에 연결 데이터방식에 대한 정의가 필요한듯.
//null 일경우 모든 client 전송 데이터 연결 허용.
//특정문자열을 입력하여 제한가능 한걸로 보임
var connection = request.accept(null, request.origin);
//메세지 수신 이벤트
connection.on('message', function (message) {
//String 형태로 넘어온데이터 처리
if (message.type === 'utf8') {
//로직
//ex) 헬로라는 문자열을 사용자에게 출력.
connection.send('hello');
//바이너리 데이터 처리
}else if (message.type === 'binary') {
//로직
}else{
//로직
}
});
//사용자가 연결을 끊엇을때 이벤트 처리
connection.on('close', function (reasonCode, description) {
});
});
}catch(exception){
}
nodejs 기본 제공 하는 socket.io 기술을 사용해서 구현도 가능 하지만 클라이언트 단에
관련라이브러리 js 파일을 넣어줘야한다.
위 기본 형태는 서버와 클라이언트 1:1 통신 이며 서버가 클라이언트 들에게 모두 중개 해야하는 입장이라면 추가로직이 필요할것이다.
클라이언트 코드.
var ws = new WebSocket('ws://아이피:포트');
(ssl 적용관련 설명은 따로 올릴예정)
//웹소켓을 기본적으로 하는 미지원 브라우저도 존재한다.
if('WebSocket' in window){
ws.onopen=function(e){
console.log(e);
console.log("onopen");
}
ws.onclose=function(e){
console.log(e);
console.log("onclose");
}
ws.onerror=function(e){
console.log(e);
console.log("onerror");
}
ws.onmessage = function (evt) {
console.log(e);
console.log("onerror");
};
}else{
console.log("WebSocket not supported.");
}
=================================
=================================
=================================
출처: http://nerobong2.blogspot.com/2017/01/nodejs-websocket-ssl.html
[nodejs] webSocket ssl 적용.
2. 전달받은 클라이언트는 브라우저 내부적으로 인증기관정보 및 도메인 정보를 가지고 신뢰할수 있는 도메인 유무를 확인후 랜덤으로 생성 한 대칭키를 클라이언트에게 전달한다.
3. 클라이언트는 전달받은 대칭키로 데이터및 url 을 암호화 하고 대칭키를 처음에 서버로부터 받은 공개키로 또 암호화를해서 서버로 데이터를 전송한다.
4. 서버는 받은 대칭키를 개인키로 복호화하고 복호화된 대칭키로 데이터를 다시 복호화 한다.
5. 서버에서 데이터 전송시 데이터를 개인키로 암호화후 전송한고 클라이언트는 공개키로 복호화한다.
예를들면 aaa.com 에 적용된 ssl 인증서 정보로 wss://아이피:포트 웹소켓서버에 ssl을 동일 하게 적용해도 인증업체에 도메인 등록이 되어있지 않으면 통신이 불가능 하다. 따라서 인증업체에 도메인 추가를 한후 다시 인증서를 받아서 처리하거나(그다지 추천하는 방식은아님) ssl 터널링 기술을 이용해야한다.
=================================
=================================
=================================
출처: https://www.npmjs.com/package/websocket
Installation
A few users have reported difficulties building the native extensions without first manually installing node-gyp. If you have trouble building the native extensions, make sure you've got a C++ compiler, and have done npm install -g node-gyp
first.
Native extensions are optional, however, and WebSocket-Node will work even if the extensions cannot be compiled.
In your project root:
$ npm install websocket
Then in your code:
Note for Windows Users
Because there is a small C++ component used for validating UTF-8 data, you will need to install a few other software packages in addition to Node to be able to build this module:
- Microsoft Visual C++
- Python 2.7 (NOT Python 3.x)
Current Features:
- Licensed under the Apache License, Version 2.0
- Protocol version "8" and "13" (Draft-08 through the final RFC) framing and handshake
- Can handle/aggregate received fragmented messages
- Can fragment outgoing messages
- Router to mount multiple applications to various path and protocol combinations
- TLS supported for outbound connections via WebSocketClient
- TLS supported for server connections (use https.createServer instead of http.createServer)
- Thanks to pors for confirming this!
- Cookie setting and parsing
- Tunable settings
- Max Receivable Frame Size
- Max Aggregate ReceivedMessage Size
- Whether to fragment outgoing messages
- Fragmentation chunk size for outgoing messages
- Whether to automatically send ping frames for the purposes of keepalive
- Keep-alive ping interval
- Whether or not to automatically assemble received fragments (allows application to handle individual fragments directly)
- How long to wait after sending a close frame for acknowledgment before closing the socket.
- W3C WebSocket API for applications running on both Node and browsers (via the
W3CWebSocket
class).
Known Issues/Missing Features:
- No API for user-provided protocol extensions.
Usage Examples
Server Example
Here's a short example showing a server that echos back anything sent to it, whether utf-8 or binary.
Client Example
This is a simple example client that will print out any utf-8 messages it receives on the console, and periodically sends a random number.
This code demonstrates a client in Node.js, not in the browser
Client Example using the W3C WebSocket API
Same example as above but using the W3C WebSocket API.
Request Router Example
For an example of using the request router, see libwebsockets-test-server.js
in the test
folder.
Resources
A presentation on the state of the WebSockets protocol that I gave on July 23, 2011 at the LA Hacker News meetup. WebSockets: The Real-Time Web, Delivered
=================================
=================================
=================================
출처: https://techbrij.com/node-js-tcp-server-client-promisify
Node.js: Simple TCP Server & Client and Promisify the Client
By Brij Mohan
In this post, you will see an example of simple TCP server and client in traditional javascript way and in ES6 way. Node.js has net module which provides an asynchronous network API for creating stream-based TCP or IPC servers and clients. We are going to use it to implement TCP server and client. This post is updated with Node v6.11.2.
TCP Server:
Here is an example of TCP server in Node.js:
var net = require( 'net' ); // Configuration parameters var HOST = 'localhost' ; var PORT = 1234; // Create Server instance var server = net.createServer(onClientConnected); server.listen(PORT, HOST, function () { console.log( 'server listening on %j' , server.address()); }); function onClientConnected(sock) { var remoteAddress = sock.remoteAddress + ':' + sock.remotePort; console.log( 'new client connected: %s' , remoteAddress); sock.on( 'data' , function (data) { console.log( '%s Says: %s' , remoteAddress, data); sock.write(data); sock.write( ' exit' ); }); sock.on( 'close' , function () { console.log( 'connection from %s closed' , remoteAddress); }); sock.on( 'error' , function (err) { console.log( 'Connection %s error: %s' , remoteAddress, err.message); }); }; |
TCP Client:
var net = require( 'net' ); var HOST = 'localhost' ; var PORT = 1234; var client = new net.Socket(); client.connect(PORT, HOST, function () { console.log( 'Client connected to: ' + HOST + ':' + PORT); // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client client.write( 'Hello World!' ); }); client.on( 'data' , function (data) { console.log( 'Client received: ' + data); if (data.toString().endsWith( 'exit' )) { client.destroy(); } }); // Add a 'close' event handler for the client socket client.on( 'close' , function () { console.log( 'Client closed' ); }); client.on( 'error' , function (err) { console.error(err); }); |
Output:
Server:
D:\node>node server.js server listening on {"address":"127.0.0.1","family":"IPv4","port":1234} new client connected: 127.0.0.1:62682 127.0.0.1:62682 Says: Hello World! connection from 127.0.0.1:62682 closed
Client:
D:\node>node client.js Client connected to: localhost:1234 Client received: Hello World! Client received: exit Client closed
TCP Server:
Here is an example of TCP server in Node.js:
var net = require( 'net' ); // Configuration parameters var HOST = 'localhost' ; var PORT = 1234; // Create Server instance var server = net.createServer(onClientConnected); server.listen(PORT, HOST, function () { console.log( 'server listening on %j' , server.address()); }); function onClientConnected(sock) { var remoteAddress = sock.remoteAddress + ':' + sock.remotePort; console.log( 'new client connected: %s' , remoteAddress); sock.on( 'data' , function (data) { console.log( '%s Says: %s' , remoteAddress, data); sock.write(data); sock.write( ' exit' ); }); sock.on( 'close' , function () { console.log( 'connection from %s closed' , remoteAddress); }); sock.on( 'error' , function (err) { console.log( 'Connection %s error: %s' , remoteAddress, err.message); }); }; |
TCP Client:
var net = require( 'net' ); var HOST = 'localhost' ; var PORT = 1234; var client = new net.Socket(); client.connect(PORT, HOST, function () { console.log( 'Client connected to: ' + HOST + ':' + PORT); // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client client.write( 'Hello World!' ); }); client.on( 'data' , function (data) { console.log( 'Client received: ' + data); if (data.toString().endsWith( 'exit' )) { client.destroy(); } }); // Add a 'close' event handler for the client socket client.on( 'close' , function () { console.log( 'Client closed' ); }); client.on( 'error' , function (err) { console.error(err); }); |
Output:
Server:
D:\node>node server.js server listening on {"address":"127.0.0.1","family":"IPv4","port":1234} new client connected: 127.0.0.1:62682 127.0.0.1:62682 Says: Hello World! connection from 127.0.0.1:62682 closed
Client:
D:\node>node client.js Client connected to: localhost:1234 Client received: Hello World! Client received: exit Client closed
ES6 Way:
Let’s update the code in ES6 way. It is assumed you are familiar with following ES6 features:
Class
Arrow Functions
Template literals
TCP Server:
'use strict' ; // load the Node.js TCP library const net = require( 'net' ); const PORT = 1234; const HOST = 'localhost' ; class Server { constructor(port, address) { this .port = port || PORT; this .address = address || HOST; this .init(); } init() { let server = this ; let onClientConnected = (sock) => { let clientName = `${sock.remoteAddress}:${sock.remotePort}`; console.log(` new client connected: ${clientName}`); sock.on( 'data' , (data) => { console.log(`${clientName} Says: ${data}`); sock.write(data); sock.write( 'exit' ); }); sock.on( 'close' , () => { console.log(`connection from ${clientName} closed`); }); sock.on( 'error' , (err) => { console.log(`Connection ${clientName} error: ${err.message}`); }); } server.connection = net.createServer(onClientConnected); server.connection.listen(PORT, HOST, function () { console.log(`Server started at: ${HOST}:${PORT}`); }); } } module.exports = Server; |
To test server, use following code in another file and run it
const Server = require( './server' ); new Server(); |
TCP Client:
'use strict' ; const net = require( 'net' ); const PORT = 1234; const HOST = 'localhost' ; class Client { constructor(port, address) { this .socket = new net.Socket(); this .address = address || HOST; this .port = port || PORT; this .init(); } init() { var client = this ; client.socket.connect(client.port, client.address, () => { console.log(`Client connected to: ${client.address} : ${client.port}`); client.socket.write( 'Hello World!' ); }); client.socket.on( 'data' , (data) => { console.log(`Client received: ${data}`); if (data.toString().endsWith( 'exit' )) { client.socket.destroy(); } }); client.socket.on( 'close' , () => { console.log( 'Client closed' ); }); client.socket.on( 'error' , (err) => { console.error(err); }); } } module.exports = Client; |
To test client, use following code in another file and run it
const Client =require( './client' ); new Client(); |
Output:
Server:
D:\node>node serverTest.js Server started at: localhost:1234 new client connected: 127.0.0.1:62846 127.0.0.1:62846 Says: Hello World! connection from 127.0.0.1:62846 closed
Client:
D:\node>node clientTest.js Client connected to: localhost : 1234 Client received: Hello World! Client received: exit Client closed
Promisify the Client:
In your Node application, you might need to trigger server on a particular event like on button click and you want to get ES6 Promise object for neat implementation.
See Also: JavaScript Promises: Understanding Error Handling with Example
Let’s create a method to write socket on client side and returns Promise object.
'use strict' ; const net = require( 'net' ); const PORT = 1234; const HOST = 'localhost' ; class Client { constructor(port, address) { this .socket = new net.Socket(); this .address = address || HOST; this .port = port || PORT; this .init(); } init() { var client = this ; client.socket.connect(client.port, client.address, () => { console.log(`Client connected to: ${client.address} : ${client.port}`); }); client.socket.on( 'close' , () => { console.log( 'Client closed' ); }); } sendMessage(message) { var client = this ; return new Promise((resolve, reject) => { client.socket.write(message); client.socket.on( 'data' , (data) => { resolve(data); if (data.toString().endsWith( 'exit' )) { client.socket.destroy(); } }); client.socket.on( 'error' , (err) => { reject(err); }); }); } } module.exports = Client; |
sendMessage method returns Promise object. Let’s see an example how to use it:
const Client =require( './client' ); const client = new Client(); client.sendMessage( 'A' ) .then((data)=> { console.log(`Received: ${data}`); return client.sendMessage( 'B' );} ) .then((data)=> { console.log(`Received: ${data}`); return client.sendMessage( 'C' );} ) .then((data)=> { console.log(`Received: ${data}`); return client.sendMessage( 'exit' );} ) . catch ((err) =>{ console.error(err); }) |
To test, remove following line in Server code
sock.write( 'exit' ); |
Now exit is done by our code.
Output:
Server:
D:\node>node serverTest.js Server started at: localhost:1234 new client connected: 127.0.0.1:63007 127.0.0.1:63007 Says: A 127.0.0.1:63007 Says: B 127.0.0.1:63007 Says: C 127.0.0.1:63007 Says: exit connection from 127.0.0.1:63007 closed
Client:
D:\node>node clientTest.js Client connected to: localhost : 1234 Received: A Received: B Received: C Client closed
Conclusion:
This post has an example of TCP server and client in traditional javascript and ES6 way. Also, an example of promisifying TCP client for better architecture.
Enjoy Node.js and ES6 !!
=================================
=================================
=================================
출처: https://m.blog.naver.com/PostView.nhn?blogId=pisgo&logNo=220913542449&categoryNo=0&proxyReferer=&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
node.js 를 하면서,
C++ 과의 통신이 필요해져서.. 간단하게! 만들어보게 되었습니다 ㅎㅎ
간단한 예제를 만들기 위해,
C++ TCP Server는 MSDN에 있는 소스 코드를 거의 그대로 사용하였습니다 ^^
https://msdn.microsoft.com/en-us/library/windows/desktop/ms737593(v=vs.85).aspx
구조체를 보내는 것을 통신하기 위해 위의 소스에서 구조체 하나를 선언하고,
struct CTestData {
char a;
int b;
char c[15];
};
main 에서 값을 넣어주고, CTestData temp = {'a', 6, "testdata"};
보내는 부분만 수정하였습니다.. iSendResult = send(ClientSocket, (char*)&temp, sizeof(temp), 0);
js 는 클라이언트 부분 코드는 다음과 같습니다..
var net=require('net');
var client = new net.Socket();
var chara = new Buffer(4);
var intb = new Buffer(4);
var charc = new Buffer(16);
client.connect(5555, '127.0.0.1');
client.write('message test');
client.on('data', function(data) {
//console.log('got data: ', data.toString('utf-8'));
chara = data.slice(0, 4);
intb = data.slice(4, 8);
charc = data.slice(8, 24);
console.log('char a :', chara.toString('utf-8'));
console.log('int b :', intb.readUInt8());
console.log('char c :', charc.toString('utf-8'));
client.destroy();
});
client.on('close', function() {
console.log('closed..');
});
Buffer 에 데이터를 받아오는데, 저 부분을 잘라주는 작업을 거쳤습니다 :)
이 때, char형은 원래 1byte 지만.. padding 3byte를 포함해 전송되는 것에 유의해야 합니다 !
(Memory alignment / Pack 부분에 대한 공부를 하면, 이해하기 좋습니다 ㅎㅎ)
C++ 서버를 실행시켜놓고,
node.js 를 실행시키면 구조체 값을 잘 받아오는 것을 확인할 수 있습니다 ^^
=================================
=================================
=================================
출처: https://mylko72.gitbooks.io/node-js/content/chapter8/chapter8_3.html
TCP 소켓 클라이언트 구현
아래와 같이 net.connect()
를 호출해 소켓 클라이언트를 생성한다. 연결할 port
와 host
를 전달하고, 연결 이벤트를 처리할 콜백 함수도 구현한다.
net.connect({port: 8107, host: 'localhost'}, function(){ });
콜백 함수 내에서 연결 속성을 설정한다. 아래와 같이 타임아웃이나 인코딩 설정을 할 수 있다.
this.setTimeout(500); this.setEncoding('utf8');
data
이벤트를 처리해 서버로부터 받은 데이터를 읽어오려면, 다음 핸들러를 추가한다.
this.on('data', function(data){ console.log("Read from server: " + data.toString()); ... this.end(); });
서버에 데이터를 쓰려면 write()
명령을 실행한다. 서버에 많은 데이터를 쓰거나 쓰기가 실패한 경우, drain
이벤트 핸들러를 구현해 버퍼가 비어있을 경우 다시 쓰기를 수행한다.
다음은 쓰기 실패시 처리를 위한 drain
핸들러를 구현하는 예제다. 클로저를 사용해 함수가 종료되더라도 소켓과 데이터 값들을 보존한다.
function writeData(socket, data)
{
var success = !socket.write(data);
if(!success){
(function(socket, data){
socket.once('drain', function(){writeData(socket, data);});})
(socket, data)
}
}
다음은 기본 TCP 소켓 클라이언트의 전체 구현을 보여준다. 서버에 3개의 다른 소켓이 열려있고 동시에 통신을 하고 있다. 각 클라이언트는 서로 다른 랜덤 포트 번호를 받아 생성된다.
var net = require('net');
function getConnection(connName){
var client = net.connect({port: 8107, host:'localhost'},
function() { console.log(connName + ' Connected: ');
console.log(' local = %s:%s', this.localAddress, this.localPort);
console.log(' remote = %s:%s', this.remoteAddress, this.remotePort);
this.setTimeout(500);
this.setEncoding('utf8');
this.on('data', function(data) {
console.log(connName + " From Server: " + data.toString());
this.end();});
this.on('end', function() {
console.log(connName + ' Client disconnected');});
this.on('error', function(err) {
console.log('Socket Error: ', JSON.stringify(err)); });
this.on('timeout', function() { console.log('Socket Timed Out'); });
this.on('close', function() { console.log('Socket Closed'); });
});
return client;
}
function writeData(socket, data){
var success = !socket.write(data);
if (!success){(
function(socket, data){
socket.once('drain', function(){ writeData(socket, data);});})(socket, data);}
}
var Dwarves = getConnection("Dwarves");
var Elves = getConnection("Elves");
var Hobbits = getConnection("Hobbits");
writeData(Dwarves, "More Axes");
writeData(Elves, "More Arrows");
writeData(Hobbits, "More Pipe Weed");
TCP 소켓 서버 구현
소켓 서버는 Server 객체의 close
와 error
이벤트와 클라이언트 Socket 객체의 연결 이벤트를 처리해야 한다.
Server 객체를 사용해 소켓 서버를 구현하는 첫 단계는 아래와 같이 net.createServer()
호출을 통해 소켓 서버를 생성한다. 연결 콜백 핸들러를 제공하고 listen()
호출을 통해 포트 수신을 시작한다.
var server = net.createServer(function(client){ ... }); server.listen(8107, function(){ ... });
listen
콜백 핸들러 안에서 서버 객체의 close
와 error
이벤트를 지원할 핸들러를 추가한다.
server.on('close', function(){ console.log('Server Terminated'); }); server.on('error', function(err){ ... });
connection
이벤트 호출 내에서는 연결 속성을 설정한다. 아래와 같이 타임아웃이나 인코딩 설정을 할 수 있다.
this.setTimeout(500); this.setEncoding('utf8');
data
이벤트 핸들러를 사용해 클라이언트에서 받은 데이터를 읽어오려면, 다음 핸들러를 추가한다.
this.on('data', function(data){ console.log("Reeived from client: " + data.toString()); ... });
다음은 기본 TCP 소켓 서버의 전체 구현을 보여준다. 소켓 서버는 8107 포트로 연결을 받고, 데이터를 읽은 후 클라이언트에 문자열을 쓴다.
var net = require('net');
var server = net.createServer(function(client) {
console.log('Client connection: ');
console.log(' local = %s:%s', client.localAddress, client.localPort);
console.log(' remote = %s:%s', client.remoteAddress, client.remotePort);
client.setTimeout(500);
client.setEncoding('utf8');
client.on('data', function(data) { console.log('Received data from client on port %d: %s',
client.remotePort, data.toString());
console.log(' Bytes received: ' + client.bytesRead);
writeData(client, 'Sending: ' + data.toString());
console.log(' Bytes sent: ' + client.bytesWritten); });
client.on('end', function() {
console.log('Client disconnected');
server.getConnections(function(err, count){
console.log('Remaining Connections: ' + count); });
});
client.on('error', function(err) {
console.log('Socket Error: ', JSON.stringify(err)); });
client.on('timeout', function() {
console.log('Socket Timed out');
});
});
server.listen(8107, function() {
console.log('Server listening: ' + JSON.stringify(server.address()));
server.on('close', function(){ console.log('Server Terminated'); });
server.on('error', function(err){ console.log('Server Error: ', JSON.stringify(err));
});
});
function writeData(socket, data){
var success = !socket.write(data);
if (!success){ (function(socket, data){
socket.once('drain', function(){
writeData(socket, data);
});
})(socket, data);
}
}
=================================
=================================
=================================
출처: http://ohgyun.com/370
작업한 코드는 github에 넣어뒀다.
해결책:
=================================
=================================
=================================
*기타관련링크
- http://niceman.tistory.com/109 //html5 websocket 예제
- https://techbrij.com/node-js-tcp-server-client-promisify //ES6 버전으로 서버, 클라이언트 구현
- http://chaeyoungdo.tistory.com/22
- https://www.slideshare.net/hiscale/111217
- http://namik.tistory.com/114
- https://gist.github.com/tedmiston/5935757
- http://ourcstory.tistory.com/67
- https://blog.outsider.ne.kr/542
- https://dololak.tistory.com/128
- https://www.zerocho.com/category/NodeJS/post/57df854f5f0b02001505fef2
- https://skout90.github.io/2017/08/15/Node.js/3.%20%EC%86%8C%EC%BC%93%ED%86%B5%EC%8B%A0/
- https://okdevtv.com/kr/socket.io-chat-kr.html
- https://poiemaweb.com/nodejs-socketio
- https://code.i-harness.com/ko-kr/q/61d33e
- https://nesoy.github.io/articles/2017-04/Nodejs-Network
- http://egloos.zum.com/rucaus/v/2495639
- https://stackoverflow.com/questions/7340475/client-side-tcp-with-node-js-socket-io
=================================
=================================
=================================
댓글 영역