当前位置:网站首页>Nodejs uses net module to create TCP server and client

Nodejs uses net module to create TCP server and client

2022-06-09 08:32:00 Jieyou grocery store Q

1、 Preface

Here I have to say TCP and websocket The difference between communication :

difference
according to OSI Network layered model ,IP It's network layer protocol ,TCP It's the transport layer protocol , and HTTP It's the application layer protocol . Between the three ,SPDY and WebSocket Are all with HTTP Related agreements , and TCP yes HTTP The underlying protocol .

WebSocket Then provide to use a TCP The mechanism of two-way communication through connection , Including network protocol and API, To replace web pages and servers with HTTP Polling is a mechanism for two-way communication .
In essence ,WebSocket It's not limited to HTTP Agreed , But because there are a lot of HTTP infrastructure , agent , Filter , Identity authentication and so on ,WebSocket To borrow HTTP and HTTPS The port of .

Due to the use HTTP The port of , therefore TCP The handshake message after the connection is established is based on HTTP Of , Judging by the server, this is a HTTP Agreement or WebSocket agreement .
WebSocket Except for the handshake when establishing and closing the connection , Data transmission and HTTP It doesn't matter at all .

In a word

websocket A handshake is established by http Of , The real transmission will not be carried out later HTTP Interaction , But the beginning websocket Data frame protocol for . Realize the data exchange between client and server

So use Nodejs Create a TCP What about servers? ?

2、 Fulfill the requirements

The server can send messages to clients in groups , It should also support directional sending of information

3、 Simple implementation of the server

net The module is Nodejs Built in basic network module , By using net, You can create a simple tcp The server

server.listen(port[,host][,backlog][,callback])
port The parameter is the port number to listen to , Parameter values for 0 A port number will be randomly assigned when .
host For server address .
backlog Is the maximum length of the waiting queue
callback Is the callback function

Callback events :
connection: Triggered when the current new link is created , The parameters of the callback function are socket Connection object , Same as net.createServer The second function parameter of .
close:TCP Triggered when the server shuts down , The callback function has no parameters
error:TCP Triggered when an error occurs on the server , The parameters of the callback function are error object
listening: call server.listen The callback triggered when

//  introduce NET
const net = require('net');

//  establish TCP The server 
const server = net.createServer(function (client) {
    
    console.log('someones connects');

    //  Receiving data from clients 
    client.on('data', function (data) {
    
        setTimeout(() => {
    
            client.write(' The server sends a notification ');
        }, 3000);
        console.log(' The server receives data from the client :', data.toString('utf-8'));
    });

    //  Client connection closed 
    client.on('close', function (err) {
    
        console.log(' Client offline ');
    });

    //  Client connection error 
    client.on('error', function (err) {
    
        console.log(' Client connection error ');
    });
});

//  Listen for client connections 
server.listen(
    {
    
        port: 9001,
        host: '127.0.0.1',
    },
    function () {
    
        console.log('server start listening');
    }
);

// Set the callback function during listening 
server.on('listening', function () {
    
    const {
     address, port } = server.address();
    console.log('server is running: ' + address + ':' + port);
});

// Set the callback function when closing 
server.on('close', function () {
    
    console.log('sever closed');
});

// Set the callback function in case of error 
server.on('error', function () {
    
    console.log('sever error');
});

4、 Simple client implementation

const net = require('net');

const sock = net.connect(
    {
    
        port: 9001,
        host: '127.0.0.1',
    },
    function () {
    
        console.log('connected to server!');
    }
);

//  Successful connection 
sock.on('connect', function () {
    
    console.log('connect success');
    //  Send data to the server 
    sock.write(" Test data ", 'utf8');
});

//  Receive information from the server 
sock.on('data', function (data) {
    
    console.log(' Received the information from the server :', data.toString('utf-8'));
});

//  An error occurs in the calling event 
sock.on('error', function (e) {
    
    console.log('socket error', e);
});

// socket Closed Events 
sock.on('close', function () {
    
    console.log('socket close');
});

//  The other party sent an event to close the packet 
sock.on('end', function () {
    
    console.log('socket end');
});

 Insert picture description here
 Insert picture description here
 Insert picture description here

5、 Logic implementation

The simple example above , The group sending function has been realized , After the server sends a message , All connected clients can receive messages .

What if you send a message one-to-one ?
Because each connection between client and server does not have an alias , We can only get the client's IP and PORT, So we simply put IP+PORT Spliced as SessionId As the only one ID,
Return to all Client Instances are stored

//  Custom client connections SESSIONID
const {
     remoteAddress, remotePort } = client;
client.name = `${
      remoteAddress}:${
      remotePort}`;
/** *  Storage client , One to many , Or one-on-one , radio broadcast  * clients = [{name:  Client alias , sessionId:  Unique session ID,client: Client connection instance }] **/
const clients = [];
//  Storage 
function storeClient(client, name = '') {
    
    if (!client || !client.remoteAddress || !client.remotePort) return;
    const {
     remoteAddress, remotePort } = client;
    const sessionId = `${
      remoteAddress}:${
      remotePort}`;
    const existClient = clients.find(m => m.sessionId == sessionId);
    //  If it doesn't exist , Storage instance 
    if (!existClient) {
    
        clients.push({
    
            name,
            sessionId,
            client,
        });
    } else {
    
        //  If there is , to update 
        existClient.client = client;
        existClient.name = name;
    }
}

What if the server wants to send messages through an alias , What to do ?
The client can connect successfully at the first time , Synchronize alias to server , So the server knows the alias of the client

//  The event of successful connection invocation 
sock.on('connect', function () {
    
    console.log('connect success');
    //  Synchronization server , Basic client information 
    const info = {
    
        type: 'sync',
        clientName: 'Client-1',
        message: ' Synchronize basic information ',
    };
    const message = `${
      info.clientName} Synchronize the basic information to the server ${
      info.message}`;
    sock.write(JSON.stringify(info), 'utf8');
});

6、 Complete code

Server side

const net = require('net');

/** *  Storage client , One to many , Or one-on-one , radio broadcast  * clients = [{name:  Client alias , sessionId:  Unique session ID,client: Client connection instance }] **/
const clients = [];

//  establish 
const server = net.createServer(function (client) {
    
    //  Custom client connections SESSIONID
    //  Or it can be defined on the client side UUID, Synchronize information 
    const {
     remoteAddress, remotePort } = client;
    client.name = `${
      remoteAddress}:${
      remotePort}`;
    //  Storage 
    storeClient(client);
    console.log('[ The client has accessed ]: ', client.name);
    console.log(
        '[ All clients that have been connected at present ]: ',
        clients.map(m => m.sessionId)
    );

    //  Listen for data from the client 
    client.on('data', function (data) {
    
        try {
    
            //  Be sure to constrain the fixed message template , here data The agreement is JSON Formatted data 
            const _data = JSON.parse(data);
            const {
     type, clientName, message } = _data;
            if (type == 'sync') {
    
                //  Sync information 
                storeClient(client, clientName);
            } else if (type == 'info') {
    
                //  Message exchange 
            }
            console.log(
                ' The server receives a message from the client ' + client.name + ' The data of ',
                message.toString('utf-8')
            );
        } catch (error) {
    }
    });

    //  Handle when the client disconnects ,
    //  Prompt the user to disconnect and leave , Delete client connection pool 
    client.on('close', function () {
    
        const index = clients.findIndex(m => m.sessionId == client.name);
        if (index >= 0) clients.splice(index, 1);
        console.log(
            '【all clients】',
            clients.map(m => m.sessionId)
        );
        console.log(client.name, ' Get offline ');
    });

    //  Client connection error 
    client.on('error', function (err) {
    
        console.log(client.name + '  Connection error ', err);
    });
});

//  radio broadcast 
const broadcast = ({
      clientName, message }) => {
    
    //  Directional broadcast 
    if (clientName) {
    
        const client = clients.find(m => m.name == clientName);
        client && client.client.write(message);
    } else {
    
        //  Mass hair 
        clients.map(m => {
    
            m.client.write(message);
        });
    }
};

//  test 
let testTimeout = null;
server.on('connection', function () {
    
    clearTimeout(testTimeout);
    testTimeout = setTimeout(() => {
    
        console.log(' Inform everyone : I'm here to get supplies ');
        broadcast({
     message: '\n\r We have come to collect supplies ' });

        console.log(' notice Client-1:  Hurry to make nucleic acid ,  Everything is waiting for you ');
        broadcast({
     clientName: 'Client-1', message: '\n\r Hurry to make nucleic acid ,  Everything is waiting for you ' });

        console.log(' notice Client-2:  Come and do nucleic acid later ');
        broadcast({
     clientName: 'Client-2', message: '\n\r Come and do nucleic acid later ' });
    }, 10000);
});

server.on('listening', function () {
    
    console.log(' Waiting for the connection ...');
});

//  Port listening 
server.listen({
    
    port: 9000,
    host: '127.0.0.1',
});

//  Call when listening for errors 
server.on('error', function () {
    
    console.log('listen error');
});

server.on('close', function () {
    
    console.log('server stop listener');
});

//  Storage 
function storeClient(client, name = '') {
    
    if (!client || !client.remoteAddress || !client.remotePort) return;
    const {
     remoteAddress, remotePort } = client;
    const sessionId = `${
      remoteAddress}:${
      remotePort}`;
    const existClient = clients.find(m => m.sessionId == sessionId);
    //  If it doesn't exist , Storage instance 
    if (!existClient) {
    
        clients.push({
    
            name,
            sessionId,
            client,
        });
    } else {
    
        //  If there is , to update 
        existClient.client = client;
        existClient.name = name;
    }
}

client Client-1

const net = require('net');

// net.Socket,
const sock = net.connect(
    {
    
        port: 9000,
        host: '127.0.0.1',
    },
    function () {
    
        console.log('connected to server!');
    }
);

//  The event of successful connection invocation 
sock.on('connect', function () {
    
    console.log('connect success');
    //  Synchronization server , Basic client information 
    const info = {
    
        type: 'sync',
        clientName: 'Client-1',
        message: ' Synchronize basic information ',
    };
    const message = `${
      info.clientName} Synchronize the basic information to the server ${
      info.message}`;
    console.log(message);
    sock.write(JSON.stringify(info), 'utf8');

    //  Delay sending data 
    setTimeout(() => {
    
        //  The message template 
        const info = {
    
            type: 'info',
            clientName: 'Client-1',
            message: '1111',
        };
        const message = `${
      info.clientName} Send information to the server :${
      info.message}`;
        console.log(message);
        sock.write(JSON.stringify(info), 'utf8');
    }, 3000);
});

//  When data occurs , call ;
sock.on('data', function (data) {
    
    console.log('Client-1  Received the information from the server :', data.toString('utf-8'));
});

//  An error occurs in the calling event 
sock.on('error', function (e) {
    
    console.log('error', e);
});

// socket Closed Events 
sock.on('close', function () {
    
    console.log('close');
}); 

//  The other party sent an event to close the packet 
sock.on('end', function () {
    
    console.log('end');
});

client Client-2

const net = require('net');

// net.Socket,
const sock = net.connect(
    {
    
        port: 9000,
        host: '127.0.0.1',
    },
    function () {
    
        console.log('connected to server!');
    }
);

//  The event of successful connection invocation 
sock.on('connect', function () {
    
    console.log('connect success');
    //  Synchronization server , Basic client information 
    const info = {
    
        type: 'sync',
        clientName: 'Client-2',
        message: ' Synchronize basic information ',
    };
    const message = `${
      info.clientName} Synchronize the basic information to the server ${
      info.message}`;
    console.log(message);
    sock.write(JSON.stringify(info), 'utf8');

    //  Delay sending data 
    setTimeout(() => {
    
        //  The message template 
        const info = {
    
            type: 'info',
            clientName: 'Client-2',
            message: '222',
        };
        const message = `${
      info.clientName} Send information to the server :${
      info.message}`;
        console.log(message);
        sock.write(JSON.stringify(info), 'utf8');
    }, 3000);
});

//  When data occurs , call ;
sock.on('data', function (data) {
    
    console.log('Client-2  Received the information from the server :', data.toString('utf-8'));
});

//  An error occurs in the calling event 
sock.on('error', function (e) {
    
    console.log('error', e);
});

// socket Closed Events 
sock.on('close', function () {
    
    console.log('close');
});

//  The other party sent an event to close the packet 
sock.on('end', function () {
    
    console.log('end');
});

 Insert picture description here
 Insert picture description here

 Insert picture description here

原网站

版权声明
本文为[Jieyou grocery store Q]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206090825280108.html