zoukankan      html  css  js  c++  java
  • 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('
    boardcast[' + signal.from + ']> ' + signal.message + '
    ');
                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}】端口`);
    });
  • 相关阅读:
    mysql查询不同用户(操作记录)的最新一条记录
    Mysql复制一条或多条记录并插入表|mysql从某表复制一条记录到另一张表
    获取股票数据接口(腾讯)
    uni-app微信相关开发问题记录:微信分享报错"包名不对,请检查包名是否与开放平台填写一致"、Android微信支付只能调起一次的问题、App微信登录与公众号微信登录的unionid不一致
    如何生成Android签名证书、安卓签名获取工具获取APP签名报错:NameNotFoundException: Signs is null的问题
    uniapp微信APP支付踩坑指南:报错errMsg: "requestPayment:fail errors"
    浅析判断一个APP是原生的还是H5页面
    uniapp nvue开发注意事项
    浅析Redis(整合Springboot、订阅发布、集群、雪崩、穿透、击穿)
    uniapp引入iconfont图标及解决真机中iconfont不显示的问题
  • 原文地址:https://www.cnblogs.com/zyl-Tara/p/9771789.html
Copyright © 2011-2022 走看看