具有 tls/ssl 加密的 Nodejs 服务器-客户端聊天系统

Nodejs server-client chat system with tls/ssl encryption

我写了一个TLS服务端-客户端聊天代码,没有错误码,但是运行不正常

我的npm版本是7.24.2,node版本是12.22.7。

当我连接到服务器时一切正常,但是当我尝试发送消息时服务器只收到一次。但是当我向客户端发送回消息时,我收到了消息。在那之后,客户端也只收到一次消息,如果我想让服务器收到其他消息,我需要发回一条消息。

index.html:

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>Server-Client system</title>
   <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
   <input type="text" placeholder="ip" id="ip"/>
   <input type="text" placeholder="port" style="width: 40px" id="port"/>
   <input type="button" value="Host a server" id="host" onclick="hostsrv()" /><input type="button" value="Connect" id="connect" onclick="connSrv()"/>
   <br><input type="button" value="Stop server" id="stopsrv" onclick="stopSrv()" /><br>
   <input type="text" placeholder="message" id="msg"/>
   <input type="button" value="Send message" onclick="sendMsg()"/>
   <script src="./index.js" ></script>
</body>
</html>

index.js:

var tls = require('tls'), fs = require('fs'), ipp = require("ip");

var ip = document.getElementById("ip");
var port = document.getElementById("port");
var msg = document.getElementById("msg");
var connBtn = document.getElementById("connect");
var hostBtn = document.getElementById("host");
var stopsrvBtn = document.getElementById("stopsrv");
var srv = null;
var client = null;

ip.value = ipp.address();
port.value = "21";

stopsrvBtn.disabled= true;

//Csatlakozás a szerverhez
async function connSrv(){
  connBtn.disabled = true;
  var _ip = ip.value, _port = port.value;

  var options = {
    rejectUnauthorized: false,
    key: fs.readFileSync('./scs/private-key.pem'), 
    cert: fs.readFileSync('./scs/public-cert.pem'),
  };

  var conn = tls.connect(_port, _ip, options, function() {
      if (conn.authorized) {
          console.log("Connection authorized by a Certificate Authority.");
      } else {
          console.log("Connection not authorized: " + conn.authorizationError);
      }
      console.log();
  },);
  conn.setEncoding('utf-8');
    
  conn.on("data", function (data) {
      console.log("SERVER> msg:\""+ data.toString()+"\"\n");
  });

  conn.on("end", function(){
    console.log("Connection end!");
    connBtn.disabled = false;
    hostBtn.disabled = false;
    client = null;
    return false;
  });
  
  while(conn.connecting){
    await new Promise(r => setTimeout(r, 200));
  }
  if(!conn.authorized && conn.authorizationError == "DEPTH_ZERO_SELF_SIGNED_CERT" || conn.authorized){
    connBtn.disabled = true;
    hostBtn.disabled = true;
    console.log("Connected");
    client = conn;
  }else{
    console.log("Connection error!");
  }
}

var cc = new Array(); //The connected clients list

//Send message
function sendMsg(){
  
  if(srv != null){ //If I am the server
    if(msg.value.trim() != ""){
      for(c of cc){
        c.write(msg.value);
        console.log("ME> " + msg.value);
      }
    }
  }
  if(client != null){ //If I am a client
    if(msg.value.trim() != ""){
      client.write(msg.value);
      console.log("ME> " + msg.value);
    }
  }
  msg.value = "";
}


//Stop the server
function stopSrv(){
  if(srv !=null){
    stopsrvBtn.disabled= true;
    srv.close();
    cc.forEach(client =>{
      client.destroy(); //Kick the clients
    });
    cc = new Array();
    srv = null;
  }
}


//When a client connected
onConnection = socket => {
  console.log("Connection");
  socket.on('data', (data) => {
    console.log("CLIENT> RMSG: " + data.toString());
  });
  socket.on('end', () => {
    const index = cc.indexOf(socket);
    if (index > -1) {
        cc.splice(index, 1);
    }
  });
  socket.setEncoding('utf-8');
  cc.push(socket);
};



//Host the server
async function hostsrv(){
  var options = {
      key: fs.readFileSync('./scs/private-key.pem'),
      cert: fs.readFileSync('./scs/public-cert.pem'),
  };
  var error = false;
  srv = tls.createServer(options, onConnection).listen(port.value, () =>{ });
  srv.on('error', err => { console.log(' error: ', err); srv.close(); error = true; });

  while(!srv.listening && !error){
      await new Promise(r => setTimeout(r, 200));
  }
  if(error) return false;
  else {
    console.log("Listening!");
    stopsrvBtn.disabled= false;
    connBtn.disabled = true;
    hostBtn.disabled = true;
  }
}

//Enter key
msg.addEventListener("keyup", function(event){
  if(event.keyCode == 13){
    event.preventDefault(); 
    sendMsg();
  }
});

main.js:

const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  const win = new BrowserWindow({
    width: 1200,
    height: 700,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true
    }
  })

  win.loadFile('./index.html');
  win.setMenu(null)
  win.webContents.openDevTools()
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

我找到了答案。
example.js:

socket.pause(); //Pauses the reading of data. That is, 'data' events will not be emitted. Useful to throttle back an upload.
socket.write("MESSAGE"); //Write the message
socket.resume(); //Resumes reading after a call to socket.pause()