Node.js实现WebSocket客户端

Posted MarsTokio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js实现WebSocket客户端相关的知识,希望对你有一定的参考价值。

笔者在工作中闹出了用nodejs的net.socket连接WebSocket服务器的笑话,故写文记录WebSocket的有关信息,并给出在nodejs实现WebSocket客户端的方法。

WebSocket与socket的区别

  • WebSocket是一种双向通信协议,客户端和服务器都可以发送和接收数据。socket不是协议,只是一组应用层和传输层的接口。
  • WebSocket在应用层,建立在TCP连接上。socket在传输层,是用于建立TCP连接的。socket对复杂的TCP/IP协议进行了封装,便于开发者实现TCP通信的功能。

net.socket

此类是 TCP socket 或流式 IPC 端点的抽象。详见

故net.socket是nodejs中用于实现socket通信的工具类,与WebSocket无关。

关于WebSocket

WebSocket的作用

WebSocket是一种基于TCP的应用层协议,实现了客户端和服务器的全双工通信,使得客户端和服务器都能主动向对方发送数据。一旦WebSocket连接建立,后续数据都以帧序列的形式在同一持久连接上传输,节省了网络带宽。
WebSocket适用于服务端不断有数据更新,而客户端需要及时获取数据更新的情况。只用HTTP的话,客户端为了实时显示数据更新,需要每隔一小段时间就发起一次HTTP请求获取数据,来检查是否更新。而使用WebSocket后,服务端在数据更新后可以将更新的数据通过WebSocket连接通知客户端,实现开销较小的实时显示。

WebSocket连接的建立过程

  1. 客户端和服务器通过三次握手建立TCP连接。
  2. TCP连接成功后,客户端通过HTTP协议向服务端传送WebSocket支持的版本号等信息。
  3. 服务端收到握手请求后,同样采用HTTP回复数据。
  4. 当收到连接成功的信息后,客户端和服务器通过TCP通道进行传输通信。

WebSocket的实现

客户端 - 在浏览器中运行

直接使用JS的WebSocket对象创建新的WebSocket实例并连接。连接与回调设置代码如下:

var ws = new WebSocket(\'ws://localhost:8080\');
  ws.onopen = function(e){
    console.log("连接服务器成功");
    // 向服务器发送消息
    ws.send("what`s your name?");
  }
  ws.onclose = function(e){
    console.log("服务器关闭");
  }
  ws.onerror = function(){
    console.log("连接出错");
  }
  // 接收服务器的消息
  ws.onmessage = function(e){
    let message = "message:"+e.data+"";
    console.log(message);
  }

需要注意的是:JS的WebSocket对象只能在浏览器环境中访问。详见这里

客户端 - 不在浏览器中运行

以下方法也可以在Electron的main进程中实现WebSocket客户端

WebSocket-Node

WebSocket-Node
使用WebSocket-Node创建WebSocket连接并设置回调的代码如下:

var WebSocketClient = require(\'websocket\').client;

var client = new WebSocketClient();

client.on(\'connectFailed\', function(error) {
    console.log(\'Connect Error: \' + error.toString());
});

client.on(\'connect\', function(connection) {
    console.log(\'WebSocket Client Connected\');
    connection.send("what`s your name?");
    connection.on(\'error\', function(error) {
        console.log("Connection Error: " + error.toString());
    });
    connection.on(\'close\', function() {
        console.log(\'echo-protocol Connection Closed\');
    });
    connection.on(\'message\', function(message) {
        if (message.type === \'utf8\') {
            console.log("Received: \'" + message.utf8Data + "\'");
        }

    });
    
    function sendNumber() {
        if (connection.connected) {
            var number = Math.round(Math.random() * 0xFFFFFF);
            connection.sendUTF(number.toString());
            setTimeout(sendNumber, 1000);
        }
    }
    sendNumber();
});

//下面不能加\'echo-protocol\',否则会报Can`t connect due to "Sec-WebSocket-Protocol header"的错。因为服务器没有返回对应协议规定的信息
client.connect(\'ws://localhost:8080/\'); //, \'echo-protocol\');
ws

ws
安装:
https://github.com/websockets/ws
使用ws创建WebSocket连接并设置回调的代码如下:

var ws = require("ws");
 
// url ws://127.0.0.1:6080
// 创建了一个客户端的socket,然后让这个客户端去连接服务器的socket
var sock = new ws("ws://localhost:8080/");
sock.on("open", function () {
    console.log("connect success !!!!");
    sock.send("HelloWorld");
});
 
sock.on("error", function(err) {
    console.log("error: ", err);
});
 
sock.on("close", function() {
    console.log("close");
});
 
sock.on("message", function(data) {
    console.log(data);
});

服务端

nodejs-websocket

安装:
npm install nodejs-websocket
创建服务并设置回调函数:

var ws = require("nodejs-websocket")

// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {
    console.log("New connection")
    conn.on("text", function (str) {
        console.log("Received "+str)
        conn.sendText(str.toUpperCase()+"!!!")
    })
    conn.on("close", function (code, reason) {
        console.log("Connection closed")
    })
}).listen(8001)
ws

创建服务并设置回调函数:

const WebSocket = require(\'ws\');

const wss = new WebSocket.Server({ port: 8080 });

wss.on(\'connection\', function connection(ws) {
  ws.on(\'message\', function incoming(message) {
    console.log(\'received: %s\', message);
  });

  ws.send(\'something\');
});

WebSocket与Socket.io

这是另一个容易混淆的地方。虽然socket.io和WebSocket都支持实时通信,但是它们并不能混用。

Socket.io不是Websocket,它只是将Websocket和轮询 (Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。也就是说,Websocket仅仅是 Socket.io实现实时通信的一个子集。因此Websocket客户端连接不上Socket.io服务端,当然Socket.io客户端也连接不上Websocket服务端。
详见

故如果要使用socket.io进行实时通信,必须同时使用socket.io-client作为客户端,socket.io作为服务端。

以上是关于Node.js实现WebSocket客户端的主要内容,如果未能解决你的问题,请参考以下文章

细说WebSocket -- Node.js篇

Node.js网络编程--WebSocket协议

node.js基于websocket实时通信的实现—GoEasy

node.js Websocket实现扫码二维码登录---GoEasy

基于 Unix Socket 的可靠 Node.js HTTP 代理实现(支持 WebSocket 协议)

Node.js 网络编程(下)实现TCPUDPWebSocket的创建