4

Node.js转发websocket数据到tcp服务器

 2 years ago
source link: https://www.myfreax.com/node-js-forwards-websocket-to-tcp-server/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
更新于 2022/05/8 |  创建于 2022/05/8

Node.js转发websocket数据到tcp服务器

Node.js转发websocket数据到tcp服务器

很多时候,当您与服务器进行实时通讯时,在浏览器端可以使用的方式包括长轮询,短轮询以及WebSocket。由于TCP也是一种实时通讯协议,你可能会存在与TCP服务器进行消息传递的场景。

浏览器仅支持Websocket的实时通讯,要想与后端TCP服务器通讯,你可能需要像websockify或者websockify-js类似这样的项目。但有时候处于调试目的,你可能需要自己实现一个Websocket转发到TCP服务器隧道。

在本教程中,我们将说明如何实现Webscoekt到TCP服务器的转发使用Node.js,你可将这个实现称为Websocket隧道Tunel或者websocket代理。还包括使用TypeScript/Javascript创建websocket客户端和websocket服务器,使用Node.js/Typescript创建TCP客户端与TCP服务器。完成websocket的数据到TCP的转发。

Webscoekt客户端

我们的websocket客户端很简单仅仅是发送一个消息,然后将此消息打印在浏览器开发工具的控制台console中。我们建议使用Typescript创建Webscoekt客户端,但你也可以使用Javascript。

现在选择一个你喜欢创建前端项目的工具。比如ViteCreate React App。如果你喜欢从头开始可以使用webpack等类似工具创建项目。在本教程中,我们将使用Vite创建一个Typescript项目。

使用vite创建一个Typescript前端项目,我们将会使用Vue作为模板,但我们不需要编写Vue代码。运行以下yarn命令创建Typescript前端项目:

yarn create vite

这将会下载Vite的模板创建,此过程需要一些时间,具体取决你的网络。当完成后会在终端提示你填写项目名称,选择一个你要使用的框架,然后选择所使用的语言ts是Typscript,如果没有ts后缀则是Javascript:

success Installed "[email protected]" with binaries:
      - create-vite
      - cva
✔ Project name: … websocket-client
✔ Select a framework: › vue
✔ Select a variant: › vue-ts

Scaffolding project in /home/myfreax/work/typescript/wsc...

如上所示,我们选择Vue作为框架,然后使用Typescript作为主要编写语言。至此前端项目已经创建完成。

现在我们使用vscode打开项目并安装项目Node.js模块依赖,如果你Linux用户你可以使用cd命令切换到项目目录。然后使用yarn命令安装模块依赖,再后运行vscode打开项目

cd wsc
yarn
code .

当使用使用vscode打开项目后,使用以下Typescript代码替换src/main.ts文件。这将创建一个简单的websocket客户端,仅发送一个helloworld消息,然后接收消息并打印在浏览器控制台。

export async function main() {
  const websocket = new WebSocket("ws://127.0.0.1:8080");
  websocket.onclose = () => console.info("websoket connection closed");
  websocket.onopen = () => console.info("websoket connected");
  websocket.onmessage = (event) => console.info(event.data);
  websocket.onerror = (event) => console.info(event);
}
main().then().catch(console.error);

至此,Websocket客户端已经创建完成,如果你需要在浏览器运行该代码请运行以下yarn命令:

yarn dev

然后在浏览器打开地址http://localhost:3000/

TCP服务器

TCP服务器的代码也是非常简单。该TCP服务器接收到消息后,不做任何处理发送回TCP客户端,这非常适合用于调试。也经常称为回显服务器。

现在我们将使用已经创建好的Typescript/Node.js模板项目typescript-backend-template创建后端项目,可以节省不必要的项目配置时间,例如配置Typescript,Vscde的调试配置,监听文件变化重启Node.js配置等。

我们不建议你使用Vite创建前端项目一样创建后端项目。除非你非常熟悉Typescript每一项配置参数,否则你会遇到ES模块导入的错误。

运行以git命令创建使用我们模板创建Node.js项目,然后使用cd命令切换到tcp-server目录中并安装Node.js模块依赖,再后使用vscode打开tcp-server项目。

git clone [email protected]:myfreax/typescript-backend-template.git tcp-server
cd tcp-server
yarn
code .

当使用使用vscode打开项目后,使用以下Typescript代码替换src/main.ts文件。这将创建一个简单的TCP服务器。

import { Server, Socket } from 'net';
const port = 8081;
const server = new Server();
server.listen(port, function () {
  console.log(
    `Server listening for connection requests on socket localhost:${port}`,
  );
});

server.on('connection', function (socket: Socket) {
  console.log('A new connection has been established.');
  socket.on('data', function (buffer) {
    socket.write(buffer);
    console.log(`Data received from client`);
  });
  socket.on('end', function () {
    console.log('Closing connection with the client');
  });
  socket.on('error', function (err: Error) {
    console.error(err);
  });
});

至此,我们已经完成TCP服务器端项目的创建,如你需要运行它,运行以下yarn命令即可启动tcp服务器。此命令监听文件的变化以重新启动你的Node.js应用程序。

该命令已经在tcp服务器项目的pakcage.json中声明,你直接运行它:

yarn start:dev

Webscoekt转发TCP

要实现Webscoekt数据装发到TCP服务器。我们还必须实现TCP客户端和Websocket服务器。由于Node.js没有默认Websocket的实现。因此我们将使用第三方模块的websocket实现。

ws是Node.js的Websocket的实现,简单易用、快速且经过全面测试的Node.js WebSocket客户端和服务器,在这里我们仅使用WebSocket服务器端。

为了实现Websocket到TCP数据转发。我们继续使用Node.js/Typescript后端模板typescript-backend-template创建项目websocket-tcp。

运行以下命令创建websocket-tcp项目,该项目和TCP项目一样,也是后端类型项目:

git clone [email protected]:myfreax/typescript-backend-template.git webscoket-tcp
cd webscoket-tcp
yarn
code .

创建项目完成后,使用yarn命令添加ws模块到你的webscoket-tcp项目中:

yarn add ws

然后使用以下Typescript代码替换src/main.ts文件。这代码很简单,下面我们简单解释一下代码。

import WebSocket, { WebSocketServer } from 'ws';
import { Socket } from 'net';
const tcp = new Socket();
tcp.connect(8081, '127.0.0.1', function () {
  console.log('Connected Server');
});
tcp.on('close', function () {
  console.log('Server Connection closed');
});
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', function connection(ws) {
  ws.on('message', function message(data: WebSocket.RawData) {
    const u8 = data.valueOf() as Uint8Array;
    tcp.write(u8);
  });
  tcp.on('data', function (data: Buffer) {
    ws.send(data);
  });
});

它使用Node.js net模块的socket对象,创建一个TCP连接通过connect方法,连接到127.0.0.1:8081即本地主机8081端口。然后创建WebSocketServer的实例创建websocket服务器在端口8080

当websocket服务器的message事件接收到浏览器端的数据后,它是一个RawData数据,而TCP socekt的write方法要求参数是Uint8Array。因此我们需要RawData转换为Uint8Array

RawDatavalueOf方法可帮助我们将websocket的数据转换为Uint8Array。这是也是实现转发数据的核心与最难的一点。

现在我们实现了数据的转换,接下来使用TCP socket的write发送TCP服务器。我们的TCP服务器将次数据不做任何处理返回到TCP客户端。

TCP socket监听data事件接收来自TCP服务器的数据,该数据是一个Buffer,因此我们不需要做任何处理即可将该数据使用websocket的send方法发送到浏览器。整个过程已经完成。

你已学会如何使用Node.js/Typescript创建websocket客户端/服务器以及TCP服务器/客户端。在浏览器创建websocekt客户端。转发websocket数据到TCP服务器。如果您有任何疑问或反馈,请随时在下面评论。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK