摘要:本文,我們通過和實現(xiàn)一個在線聊天室的。創(chuàng)建三個對象,一個作為多人在線聊天室,一個作為提示當(dāng)前在線人數(shù),還有一個為的作為在線人數(shù)顯示文本。創(chuàng)建一個對象為作為消息發(fā)送輸入框,用戶可以在此輸入消息進行發(fā)送。
本文,我們通過Egret和Node.js實現(xiàn)一個在線聊天室的demo。主要包括:聊天,改用戶名,查看其他用戶在線狀態(tài)的功能。大致流程為,用戶訪問網(wǎng)頁,即進入聊天狀態(tài),成為新游客,通過底部的輸入框,可以輸入自己想說的話,點擊發(fā)布,信息呈現(xiàn)給所有在聊天的人的頁面。用戶可以實時修改自己的昵稱,用戶離線上線都會實時廣播給其他用戶。
體驗鏈接 http://7hds.com:8888/
下圖為最終制作完成的聊天面板
WebSocket服務(wù)器可以用其他語言編寫,本文采用的方法建立在Node.js上 。
在Node.js中我們使用ws第三方模塊來實現(xiàn)服務(wù)器業(yè)務(wù)邏輯的快速搭建,還需使用uuid模塊生成隨機id,你需要使用npm包管理器來安裝ws、uuid模塊。使用以下命令:
npm install ws -g npm install uuid -g
安裝完成之后,使用終端工具進入服務(wù)器目錄,開始編寫代碼:
//引入ws模塊 var WebSocket = require("ws"); //創(chuàng)建websocket服務(wù),端口port為:**** var WebSocketServer = WebSocket.Server, wss = new WebSocketServer({port: 8180}); //引入uuid模塊 var uuid = require("node-uuid"); //定義一個空數(shù)組,存放客戶端的信息 var clients = []; //定義發(fā)送消息方法wsSend //參數(shù)為 type:類型 //client_uuid:隨機生成的客戶端id //nickname:昵稱 //message:消息 //clientcount:客戶端個數(shù) 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); } }//發(fā)送消息 else { wsSend("message", client_uuid, nickname, message,clients.length); } }); //關(guān)閉socket連接時 var closeSocket = function(customMessage) { //遍歷客戶端 for(var i=0; i 服務(wù)器端主要是接收信息,判斷是聊天信息還是重命名信息,然后發(fā)送廣播。同時,當(dāng)用戶連接上服務(wù)器端或者關(guān)閉連接時,服務(wù)器也會發(fā)送廣播通知其他用戶。
我們封裝了wsSend函數(shù)用來處理消息的廣播。對每個連接的用戶,我們默認(rèn)給他分配為游客。為了實現(xiàn)廣播,我們用clients數(shù)組來保存連接的用戶。
將編寫好的文件保存為server.js,在終端工具中,使用node server.js來啟動你剛剛編寫的服務(wù)器。如果終端沒有報錯,證明你的代碼已經(jīng)正常運行。
在實際項目中,服務(wù)器邏輯遠遠比此示例復(fù)雜得多。服務(wù)器端完成后,再來編寫客戶端代碼。
界面非常簡單,我們通過兩張圖片來實現(xiàn)界面效果,首先創(chuàng)建我們的聊天界面,此項目中為了方便我們使用EUI進行快速開發(fā)。如下圖:
首先創(chuàng)建一個Image來放置我們的背景圖。
創(chuàng)建三個Label對象,一個作為title:“多人在線聊天室”,一個作為提示:“當(dāng)前在線人數(shù)”,還有一個id為lb_online的作為在線人數(shù)顯示文本。
創(chuàng)建一個EditableText對象id為input_msg作為消息發(fā)送輸入框,用戶可以在此輸入消息進行發(fā)送。
創(chuàng)建一個Button對象id為btn_ok,點擊按鈕可以執(zhí)行發(fā)送消息動作。
創(chuàng)建界面的操作和WebSocket對象創(chuàng)建動作在同時進行,在init方法中創(chuàng)建WebSocket對象,并執(zhí)行服務(wù)器連接操作,代碼如下:
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"); } }由于服務(wù)器開放了8180端口,我們也需要使用8180端口進行連接。當(dāng)連接成功,可執(zhí)行onopen方法。
服務(wù)器連接成功了,在控制臺打印 "Connection to server opened"。
onmessage方法中讀取服務(wù)器傳遞過來的數(shù)據(jù),并通過appendLog方法將數(shù)據(jù)顯示在對應(yīng)的文本里,
使用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; /**在線人數(shù) */ self.lb_online.text = clientcount; } /**點擊OK發(fā)送 */ 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; }最后我們來編寫發(fā)送消息的函數(shù),在btn_ok中egret.TouchEvent.TOUCH_TAP點擊之后的相應(yīng)函數(shù)為sendMessage方法。
/**發(fā)送消息 */ private sendMessage() { var message = this.input_msg.text; if (message.length < 1) { // console.log("不能發(fā)送空內(nèi)容!"); return; } this.ws.send(message); /**清空輸入框內(nèi)容 */ this.input_msg.text = ""; }如果輸入框中內(nèi)容不為空的話就將數(shù)據(jù)通過 this.ws.send(message); 發(fā)送給服務(wù)器,并清除輸入框的內(nèi)容。
最終運行后,我們就可以實現(xiàn)多人在線聊天功能了。
完整版代碼如下:
class Chat extends eui.Component implements eui.UIComponent { /**在線人數(shù)文本 */ 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連接 */ //線上測試鏈接,服務(wù)端代碼需在服務(wù)器啟動 //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; /**在線人數(shù) */ self.lb_online.text = clientcount; } /**點擊OK發(fā)送 */ this.btn_ok.addEventListener(egret.TouchEvent.TOUCH_TAP, this.sendMessage, this); } /**發(fā)送消息 */ private sendMessage() { var message = this.input_msg.text; if (message.length < 1) { // console.log("不能發(fā)送空內(nèi)容!"); return; } this.ws.send(message); /**清空輸入框內(nèi)容 */ 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增加了客戶端與服務(wù)器的互動,同時也實現(xiàn)了客戶端之間的聯(lián)系。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/97622.html
摘要:用偽代碼來模擬下長輪詢的過程前端利用下面函數(shù)進行請求后端代碼做如下更改利用隨機數(shù)的大小來模擬是否有新數(shù)據(jù)有新數(shù)據(jù)來了長輪詢的確減少了請求的次數(shù),但是它也有著很大的問題,那就是耗費服務(wù)器的資源。 寫在前面 最近由于利用node重構(gòu)某個項目,項目中有一個實時聊天的功能,于是就研究了一下聊天室,在線demo|源碼,歡迎大家反饋。這個聊天室的主要利用到了socket.io和express。這個...
摘要:好的,這樣以來我們的前期準(zhǔn)備工作就已經(jīng)完成了,下面我們來搭建聊天室對應(yīng)的客戶端和服務(wù)器端。 websocket簡介 websocket其實HTML中新增加的內(nèi)容,其本質(zhì)還是一種網(wǎng)絡(luò)通信協(xié)議,以下是websocket的一些特點: (1)因為連接在端口80(ws)或者443(wss)上創(chuàng)建,與HTTP使用的端口相同,幾乎所有的防火墻都不會阻塞WebSocket鏈接 (2)因...
摘要:好的,這樣以來我們的前期準(zhǔn)備工作就已經(jīng)完成了,下面我們來搭建聊天室對應(yīng)的客戶端和服務(wù)器端。 websocket簡介 websocket其實HTML中新增加的內(nèi)容,其本質(zhì)還是一種網(wǎng)絡(luò)通信協(xié)議,以下是websocket的一些特點: (1)因為連接在端口80(ws)或者443(wss)上創(chuàng)建,與HTTP使用的端口相同,幾乎所有的防火墻都不會阻塞WebSocket鏈接 (2)因...
摘要:聊天室的鏈接已經(jīng)失效因為我部署了一個新的網(wǎng)站,歡迎大家訪問在搭建簡單的網(wǎng)頁聊天室框架這篇文章中,我們簡單實現(xiàn)了一個聊天室,我又花了一些時間寫了個稍微復(fù)雜一點點的,大家可以通過進入聊天室或訪問。 聊天室的鏈接已經(jīng)失效!因為我部署了一個新的網(wǎng)站,歡迎大家訪問mytodo.vip 在websocket搭建簡單的網(wǎng)頁聊天室框架這篇文章中,我們簡單實現(xiàn)了一個websocket聊天室,我又花了一...
摘要:我們要做一個網(wǎng)頁版的聊天室,當(dāng)一個人發(fā)送了消息時,其他人怎么能看到這條信息呢有一個做法就是在網(wǎng)頁中不斷的運行,發(fā)送給服務(wù)器,服務(wù)器不斷返回,當(dāng)有新的消息時顯示在頁面上。這樣做毫無疑問會產(chǎn)生大量的連接,對服務(wù)器的性能和帶寬都有影響。 http協(xié)議,是客戶端每發(fā)送一個request,服務(wù)器返回一個response,無法做到服務(wù)器主動向客戶端發(fā)送數(shù)據(jù)。我們要做一個網(wǎng)頁版的聊天室,當(dāng)一個人發(fā)送...
閱讀 3149·2021-11-22 13:54
閱讀 3435·2021-11-15 11:37
閱讀 3598·2021-10-14 09:43
閱讀 3496·2021-09-09 11:52
閱讀 3595·2019-08-30 15:53
閱讀 2457·2019-08-30 13:50
閱讀 2054·2019-08-30 11:07
閱讀 885·2019-08-29 16:32