node模塊之net模塊——socket


當我們去面試的時候,常常會遇到這樣一個問題:當用戶在瀏覽器地址欄輸入一段url發出資源請求后,到服務端返回數據呈現給用戶的這個過程都發生了什么?

我們把進行通信的這兩個端(這里指的是,瀏覽器和資源獲取的地方)稱之為客戶端和服務端。我們連通兩個端進行通信,靠的就是socket這個東西。他將特定格式的內容進行傳遞,以達到客戶端和服務端通信的目的。

最近剛好在學習node的net模塊,接觸到這一塊內容。下面就來看看node中socket通信的一種實現方式。

client.js

// 客戶端

const net = require('net');

const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);

rl.question('What is your name? ', (name) => {
  name = name.trim();
  if (!name) {
    throw new Error('名字沒有提供');
  }
  // 創建於服務端的連接
  var server = net.connect({ port: 2080, host: '192.168.1.56' }, () => {

    console.log(`Welcome ${name} to 2080 chatroom`);

    // 監聽服務端發過來的數據
    server.on('data', (chunk) => {
      try {
        var signal = JSON.parse(chunk.toString().trim());
        var procotol = signal.procotol;
        switch (procotol) {
          case 'boardcast':
            console.log('\nboardcast[' + signal.from + ']> ' + signal.message + '\n');
            rl.prompt();
            break;
          default:
            server.write('再瞅試試!');
            break;
        }
      } catch (error) {
        server.write('你瞅啥!');
      }
    });

    rl.setPrompt(name + '> '); // 此時沒有寫到控制台

    rl.prompt(); // 寫入控制台

    // 輸入一行內容敲回車觸發   
    rl.on('line', (line) => {

      // {"procotol":"boardcast","from":"張三","message":"你瞅啥!"}
      var send = {
        procotol: 'boardcast',
        from: name,
        message: line.toString().trim()
      };

      server.write(JSON.stringify(send));

      rl.prompt();

    })
    .on('close', () => {
      // console.log('Have a great day!');
      // process.exit(0);
    });

  });
});

server.js

// 建立一個Socket服務端

const net = require('net');

// 用於存儲所有的客戶端連接
var clients = [];

var server = net.createServer((socket) => {

  // socket.setEncoding('utf8');

  // 哪個客戶端與我連接socket就是誰
  clients.push(socket);

  console.log(`Welcome ${socket.remoteAddress} to 2080 chatroom 當前在線${clients.length}`);

  // 觸發多次
  socket
  .on('data', clientData)
  .on('error', (err) => {
    clients.splice(clients.indexOf(socket), 1);
    console.log(`${socket.remoteAddress}下線了 當前在線${clients.length}`);
  });

});

// 廣播消息
function boardcast(signal) {
  // console.log(signal);
  // 肯定有用戶名和消息
  var username = signal.from;
  var message = signal.message;
  // 我們要發給客戶端的東西
  var send = {
    procotol: signal.procotol,
    from: username,
    message: message
  };
  // 廣播消息 遍歷每一個客戶端,並向其寫入內容
  clients.forEach(client => {
    client.write(JSON.stringify(send)); 
  });
}

// 有任何客戶端發消息都會觸發
function clientData(chunk) {
  // chunk:boardcast|張三|你瞅啥!
  // chunk:{"procotol":"boardcast","from":"張三","message":"你瞅啥!"}
  // chunk:{"procotol":"p2p","from":"張三","to":"李四","message":"瞅你咋地!"}
  try {
    var signal = JSON.parse(chunk.toString().trim());
    var procotol = signal.procotol;
    switch (procotol) {
      case 'boardcast':
        boardcast(signal);
        break;
      // case 'p2p':
      //   p2p(signal);
      //   break;
      // case 'shake':
      //   shake(signal);
      //   break;
      default:
        socket.write('再瞅試試!');
        break;
    }
  } catch (error) {
    socket.write('你瞅啥!');
  }
}

var port = 2080;
server.listen(port, (err) => {
  if (err) {
    console.log('端口被占用');
    return false;
  }
  console.log(`服務端正常啟動監聽【${port}】端口`);
});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM