博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
搭建Websocket简易聊天室
阅读量:6632 次
发布时间:2019-06-25

本文共 7017 字,大约阅读时间需要 23 分钟。

本文,我们通过Egret和Node.js实现一个在线聊天室的demo。主要包括:聊天,改用户名,查看其他用户在线状态的功能。大致流程为,用户访问网页,即进入聊天状态,成为新游客,通过底部的输入框,可以输入自己想说的话,点击发布,信息呈现给所有在聊天的人的页面。用户可以实时修改自己的昵称,用户离线上线都会实时广播给其他用户。

体验链接

下图为最终制作完成的聊天面板

搭建Websocket简易聊天室

WebSocket服务器可以用其他语言编写,本文采用的方法建立在Node.js上 。

在Node.js中我们使用ws第三方模块来实现服务器业务逻辑的快速搭建,还需使用uuid模块生成随机id,你需要使用npm包管理器来安装ws、uuid模块。使用以下命令:

npm install ws -gnpm install uuid -g

安装完成之后,使用终端工具进入服务器目录,开始编写代码:

//引入ws模块var WebSocket = require('ws');//创建websocket服务,端口port为:****var WebSocketServer = WebSocket.Server,    wss = new WebSocketServer({port: 8180});//引入uuid模块var uuid = require('node-uuid');//定义一个空数组,存放客户端的信息 var clients = [];//定义发送消息方法wsSend//参数为 type:类型//client_uuid:随机生成的客户端id//nickname:昵称//message:消息//clientcount:客户端个数function wsSend(type, client_uuid, nickname, message,clientcount) {    //遍历客户端  for(var i=0; i
= 2) { var old_nickname = nickname; nickname = nickname_array[1]; var nickname_message = "用户 " + old_nickname + " 改名为: " + nickname; wsSend("nick_update", client_uuid, nickname, nickname_message,clients.length); } }//发送消息 else { wsSend("message", client_uuid, nickname, message,clients.length); } }); //关闭socket连接时 var closeSocket = function(customMessage) { //遍历客户端 for(var i=0; i

服务器端主要是接收信息,判断是聊天信息还是重命名信息,然后发送广播。同时,当用户连接上服务器端或者关闭连接时,服务器也会发送广播通知其他用户。

我们封装了wsSend函数用来处理消息的广播。对每个连接的用户,我们默认给他分配为游客。为了实现广播,我们用clients数组来保存连接的用户。

将编写好的文件保存为server.js,在终端工具中,使用node server.js来启动你刚刚编写的服务器。如果终端没有报错,证明你的代码已经正常运行。

在实际项目中,服务器逻辑远远比此示例复杂得多。服务器端完成后,再来编写客户端代码。

界面非常简单,我们通过两张图片来实现界面效果,首先创建我们的聊天界面,此项目中为了方便我们使用EUI进行快速开发。如下图:

搭建Websocket简易聊天室

首先创建一个Image来放置我们的背景图。

创建三个Label对象,一个作为title:“多人在线聊天室”,一个作为提示:“当前在线人数”,还有一个id为lb_online的作为在线人数显示文本。

创建一个EditableText对象id为input_msg作为消息发送输入框,用户可以在此输入消息进行发送。

创建一个Button对象id为btn_ok,点击按钮可以执行发送消息动作。

创建界面的操作和WebSocket对象创建动作在同时进行,在init方法中创建WebSocket对象,并执行服务器连接操作,代码如下:

public ws;    private init() {        /**WebSocket连接 */        this.ws = new WebSocket('ws://127.0.01:8180');        this.ws.onopen = function (e) {            console.log('Connection to server opened');        }    }

由于服务器开放了8180端口,我们也需要使用8180端口进行连接。当连接成功,可执行onopen方法。

服务器连接成功了,在控制台打印 'Connection to server opened'。

onmessage方法中读取服务器传递过来的数据,并通过appendLog方法将数据显示在对应的文本里,

使用newLabel方法并将一条新消息插入到消息框中。

private init() {        /**WebSocket连接 */        this.ws = new WebSocket('ws://127.0.01:8180');        this.ws.onopen = function (e) {            console.log('Connection to server opened');        }        /**昵称 */        var nickname;        var self = this;        this.ws.onmessage = function (e) {            var data = JSON.parse(e.data);            nickname = data.nickname;            appendLog(data.type, data.nickname, data.message, data.clientcount);            console.log("ID: [%s] = %s", data.id, data.message);            //插入消息            self.group_msg.addChild(self.newLabel(data.nickname, data.message))        }        function appendLog(type, nickname, message, clientcount) {            console.log(clientcount)            /**聊天信息 */            var messages = this.list_msg;            /**提示 */            var preface_label;            if (type === 'notification') {                preface_label = "提示:";            } else if (type === 'nick_update') {                preface_label = "警告:";            } else {                preface_label = nickname;            }            self.preface_label = preface_label;            var message_text = self.message_text = message;            /**在线人数 */            self.lb_online.text = clientcount;        }        /**点击OK发送 */        this.btn_ok.addEventListener(egret.TouchEvent.TOUCH_TAP, this.sendMessage, this);    }    private newLabel(name: string, msg: string) {          var label1: eui.Label = new eui.Label();          label1.text = name + ":" + msg;          label1.textColor = 0x000000          return label1;    }

最后我们来编写发送消息的函数,在btn_ok中egret.TouchEvent.TOUCH_TAP点击之后的相应函数为sendMessage方法。

/**发送消息 */    private sendMessage() {        var message = this.input_msg.text;        if (message.length < 1) {            // console.log("不能发送空内容!");            return;        }        this.ws.send(message);        /**清空输入框内容 */        this.input_msg.text = "";    }

如果输入框中内容不为空的话就将数据通过 this.ws.send(message); 发送给服务器,并清除输入框的内容。

最终运行后,我们就可以实现多人在线聊天功能了。

完整版代码如下:

class Chat extends eui.Component implements eui.UIComponent {    /**在线人数文本 */    public lb_online: eui.Label;    /**聊天窗口 */    public scr_msg: eui.Scroller;    /**聊天信息 */    public list_msg: eui.List;    /**输入框 */    public input_msg: eui.EditableText;    /**确定按钮 */    public btn_ok: eui.Button;    /**聊天窗口消息组 */    public group_msg: eui.Group;    public constructor() {        super();    }    protected partAdded(partName: string, instance: any): void {        super.partAdded(partName, instance);    }    protected childrenCreated(): void {        this.init();        super.childrenCreated();    }    /**WebSocket */    public ws;    public preface_label;    public message_text;    private init() {        /**WebSocket连接 */         //线上测试链接,服务端代码需在服务器启动        //this.ws = new WebSocket('ws://7hds.com:8180');        this.ws = new WebSocket('ws://127.0.01:8180');        this.ws.onopen = function (e) {            console.log('Connection to server opened');        }        /**昵称 */        var nickname;        var self = this;        this.ws.onmessage = function (e) {            var data = JSON.parse(e.data);            nickname = data.nickname;            appendLog(data.type, data.nickname, data.message, data.clientcount);            console.log("ID: [%s] = %s", data.id, data.message);            //插入消息            self.group_msg.addChild(self.newLabel(data.nickname, data.message))        }        function appendLog(type, nickname, message, clientcount) {            console.log(clientcount)            /**聊天信息 */            var messages = this.list_msg;            /**提示 */            var preface_label;            if (type === 'notification') {                preface_label = "提示:";            } else if (type === 'nick_update') {                preface_label = "警告:";            } else {                preface_label = nickname;            }            self.preface_label = preface_label;            var message_text = self.message_text = message;            /**在线人数 */            self.lb_online.text = clientcount;        }        /**点击OK发送 */        this.btn_ok.addEventListener(egret.TouchEvent.TOUCH_TAP, this.sendMessage, this);    }    /**发送消息 */    private sendMessage() {        var message = this.input_msg.text;        if (message.length < 1) {            // console.log("不能发送空内容!");            return;        }        this.ws.send(message);        /**清空输入框内容 */        this.input_msg.text = "";        // console.log(this.ws.bufferedAmount);    }    private newLabel(name: string, msg: string) {        var label1: eui.Label = new eui.Label();        label1.text = name + ":" + msg;        label1.textColor = 0x000000        return label1;    }}

本文的demo增加了客户端与服务器的互动,同时也实现了客户端之间的联系。

转载于:https://blog.51cto.com/11960887/2173213

你可能感兴趣的文章
中国大数据科技传播联盟在京成立
查看>>
oracle 体系结构
查看>>
Nginx+Keepalived搭建高可用负载均衡集群
查看>>
VS2015 正式版中为什么没有了函数前面引用提示了?
查看>>
arp协议的混乱引发的思考--一个实例
查看>>
配置XenDesktop一例报错-序列不包含任何元素
查看>>
javascript理解数组和数字排序
查看>>
微软同步框架入门之五--使用WCF同步远程数据
查看>>
Last-Modified、If-Modified-Since 实现缓存和 OutputCache 的区别
查看>>
C# WinForm控件之Dock顺序调整
查看>>
NSPredicate过滤数组数据
查看>>
spark 数据预处理 特征标准化 归一化模块
查看>>
使用Solr构建企业级的全文检索(四)---------写入文档
查看>>
squid的正向代理和反向代理
查看>>
linux下命令与文件的查询
查看>>
SEO意识的网站设计:设计和SEO的完美结合可能么?
查看>>
IP 算法
查看>>
IBM_System_x3650服务器固件升级手顺
查看>>
awk单行脚本
查看>>
软件开发之通病解析
查看>>