zoukankan      html  css  js  c++  java
  • 使用原生node写一个聊天室

    在学习node的时候都会练习做一个聊天室的项目,主要使用socket.io模块和http模块。这里我们使用更加原始的方式去写一个在命令行聊天的聊天室。

    http模块,socket.io都是高度封装之后的模块,我们使用更加原始的net模块来做。

    socket

    做聊天室,我们首先要了解一下socket,用百度百科上的定义:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。socket对TCP/IP封装提供网络开发的接口,提供网络通信的接口。详细可以看看各种百科的资料。

    服务端

    1.基本接口介绍

    创建服务端

    const server = net.createServer((socket) => {
           //这里的毁掉函数中的参数就是一个socket
    }
    //监听端口和主机
    server.listen({
        port:4433,
        host:'127.0.0.1'//要想别人访问到,要写服务启动所在机子的ip地址,默认localhost
    }, () => {
        //这里是启动成功后的回调
        console.log('server bound')
    })
    

    服务创建成功之后,socket可以提供客户端(访问者)的一些信息,这里主要用的两个属性

    socket.remoteAddress :客户端的ip地址
    socket.remotePort:客户端访问的接口,这里是随机分配,注意这里的接口跟我们创建服务的接口不同,表示的意义也不一样建立网络通信连接至少要一对端口号,服务端监听的端口是为了跟服务端所在机子的其他服务区分,客户端访问这个端口的时候自然也要区分,分配不同端口
    

    socket的event事件

    //监听客户端发送过来的消息
    socket.on('data', (data) => {
          //这里data是一个buffer要转化为字符串,然后去一下两端空格
            let receive = JSON.parse(data.toString().trim());
        })
    //给客户端发送消息
    socket.write(string[,encoding]);
    

    错误处理error

    socket.on('error', (err) => {
          //在测试中发现,不去监听这个错误事件,当你客户端掉线之后服务端也会断开所以做一些错误处理
        })
    
    2.聊天设计
    聊天过程我们分三部分

    1.登录
    2.跟所有人聊
    3.跟特定对象聊
    首先我们确定聊天信息的发送格式,就像http里面有头部,内容等。我们发送的信息,应该包括发送者名字,给谁发以及发送的消息,设定为一下格式

    const send = {
        name:"",
        message:"",
        to:""
    }
    

    服务端要根据给谁发做不同的处理
    1.登录(login):我们要给所有的人发信息,XXX登录了聊天室,还要记录这个访问的socket,以便于后续给特定的人发消息,格式{username:socket}

    image.png

    2.跟所有人聊天(server):除了发消息本人要给其他人发送
    3.跟某一个人聊天(client):找到相应的socket发送消息

    socket.on('data', (data) => {
            let receive = JSON.parse(data.toString().trim());
            switch(receive.to){
                case "login":
                    DealInfo.login(receive, socket);
                    break;
                case "server":
                    DealInfo.server(receive, socket);
                    break;
                default:
                    DealInfo.client(receive, socket);
                    break;
            }
        })
    

    之前我们有监听socket的错误处理,也就是当用户掉线的时候,我们就可以把记录的socket删除掉,并提示当前用户数。这里可以从记录的socket个数求取,也可以根据以下方法

    server.getConnections((err, count) => {
                if(err){
                    throw err;
                }
                console.log(`${deleteKey}下线了 当前在线人数${count}`);
            })
    

    image.png

    客户端

    1.基本接口介绍

    创建socket连接

    const client = net.connect({
                port:4433,
                host:'127.0.0.1'//默认localhost
            }, () => {
                  //连接成功之后的回调
            })
    

    client的事件

    //监听服务端发送过来的信息
    client.on('data', (data) => {
                    //这里data是一个buffer
                    let receive = JSON.parse(data.toString().trim());
                }).on('error', (err) => {
                    //错误处理
                })
    //给服务端发送消息
    client.wirte(string[, encoding]);
    
    2.聊天设计
    基本设置

    登录:要输入聊天名再去连接客户端
    群聊或者跟某一个人聊只需要区分用户即可,跟某一个人聊的输入格式为name:message
    聊天格式:name>message

    2.1用户名

    这里我们使用readline这个模块

    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    rl.question('What is your name >', (name) => {
      //回调中的参数就所输入的信息,当输入非空的时候作为用户名,之后按我们的聊天格式输出预先样式
        //设立设定prompt的输出内容,只要调用rl.prompt()即可
        rl.setPrompt(`${name.trim()}>`);
        rl.prompt();
    }
    

    Paste_Image.png

    监听用户输入

     rl.on('line', (line) => {
                    let stdinInfo = line.trim().split(':');
                    if(stdinInfo.length == 2){
                        //跟某个用户聊天
                        send.to = stdinInfo[0];
                        send.message = stdinInfo[1];
                    }else{
                        //跟所有人聊天
                        send.to = "server";
                        send.message = stdinInfo[0];
                    }
                    client.write(JSON.stringify(send));
                    rl.prompt();
                })
    

    Paste_Image.png

    详细代码地址:https://github.com/Stevenzwzhai/node-socket-chatroom

  • 相关阅读:
    图像不存在时,可用一张通用图片代替
    中英文并排
    ThinkPHP无限级分类
    跑数据示例一
    ThinkPHP项目笔记之RBAC(权限)补充篇
    ThinkPHP项目笔记之RBAC(权限)下篇
    ThinkPHP项目笔记之RBAC(权限)中篇
    ThinkPHP项目笔记之RBAC(权限)上篇
    ThinkPHP项目笔记之RBAC(权限)基础篇
    layDate/DatePicker日期时间空间
  • 原文地址:https://www.cnblogs.com/Upton/p/6841936.html
Copyright © 2011-2022 走看看