from:https://blog.csdn.net/u010136741/article/details/51612594

【总目录】

 
 

【实例简介】

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

【效果图】

 
 
 

【客户端】

 
    web页面主要呈现在线人数,聊天信息,一个输入框和发送按钮,上代码:
 
  1. <!DOCTYPE html>
  2. <html lang="cn">
  3. <head>
  4. <title>WebSocket chart application</title>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.css">
  8. <link rel="stylesheet" href="http://cdn.bootcss.com/tether/1.3.2/css/tether.css"/>
  9. <script src="http://cdn.bootcss.com/jquery/2.2.4/jquery.js" ></script>
  10. <script src="http://cdn.bootcss.com/tether/1.3.2/js/tether.js"></script>
  11. <script src="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/js/bootstrap.js"></script>
  12. <script>
  13. var ws= new WebSocket('ws://www.liumumu.top:8180');
  14. var nickname;
  15. ws.onopen = function(e){
  16. console.log('Connection to server opened');
  17. }
  18. function appendLog(type,nickname, message,clientcount) {
  19. var messages = document.getElementById('messages');
  20. var messageElem = document.createElement("li");
  21. var preface_label;
  22. if(type==='notification') {
  23. preface_label = "<span class=\"label label-info\">*</span>";
  24. } else if(type==='nick_update') {
  25. preface_label = "<span class=\"label label-warning\">*</span>";
  26. } else {
  27. preface_label = "<span class=\"label label-success\">" + nickname + "</span>";
  28. }
  29. var message_text = "<h2>" + preface_label + "  " + message + "</h2>";
  30. messageElem.innerHTML = message_text;
  31. messages.appendChild(messageElem);
  32. var count_people = document.getElementById("count_people");
  33. count_people.innerHTML = clientcount;
  34. }
  35. ws.onmessage = function(e){
  36. var data = JSON.parse(e.data);
  37. nickname = data.nickname;
  38. appendLog(data.type,data.nickname, data.message,data.clientcount);
  39. console.log("ID: [%s] = %s", data.id, data.message);
  40. }
  41. function sendMessage(){
  42. var message = $('#message').val().trim();
  43. if(message.length<1){
  44. alert("不能发送空内容!");
  45. return;
  46. }
  47. ws.send($('#message').val());
  48. $('#message').val("");
  49. $('#message').focus();
  50. console.log(ws.bufferedAmount);
  51. }
  52. </script>
  53. </head>
  54. <body lang="cn">
  55. <div class="vertical-center">
  56. <div class="container">
  57. <h2>多人在线聊天DEMO</h2>
  58. <hr />
  59. <p>当前在线人数:<span id="count_people">0</span></p>
  60. <ul id="messages" class="list-unstyled">
  61. </ul>
  62. <hr />
  63. <form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
  64. <div class="form-group">
  65. <input class="form-control" type="text" name="message" id="message"
  66. placeholder="输入聊天内容" value="" autofocus/>
  67. </div>
  68. <button type="button" id="send" class="btn btn-primary"
  69. onclick="sendMessage();">发送!</button>
  70. </form>
  71. </div>
  72. </div>
  73. </body>
  74. </html>
    javascript 部分,连接websocket成功之后,主要是监听数据返回,和发送数据。
    当用户编辑好内容,点击发送按钮是调用sendMessage方法,发送数据,如果需要修改昵称,则发送数据格式为"/nick 昵称"。
   当服务器返回数据到客户端,我们通过appendLog方法对数据做处理,根据type字段,判断是显示用户离线在线信息,还是显示聊天信息。最后更新在线人数。
 

【服务器端】

 
    服务器端主要是接收信息,判断是聊天信息还是重命名信息,然后发送广播。同时,当用户连接上服务器端或者关闭连接时,服务器也会发送广播通知其他用户。
  1. var WebSocket = require('ws');
  2. var WebSocketServer = WebSocket.Server,
  3. wss = new WebSocketServer({port: 8180});
  4. var uuid = require('node-uuid');
  5. var clients = [];
  6. function wsSend(type, client_uuid, nickname, message,clientcount) {
  7. for(var i=0; i<clients.length; i++) {
  8. var clientSocket = clients[i].ws;
  9. if(clientSocket.readyState === WebSocket.OPEN) {
  10. clientSocket.send(JSON.stringify({
  11. "type": type,
  12. "id": client_uuid,
  13. "nickname": nickname,
  14. "message": message,
  15. "clientcount":clientcount,
  16. }));
  17. }
  18. }
  19. }
  20. var clientIndex = 1;
  21. wss.on('connection', function(ws) {
  22. var client_uuid = uuid.v4();
  23. var nickname = "游客"+clientIndex;
  24. clientIndex+=1;
  25. clients.push({"id": client_uuid, "ws": ws, "nickname": nickname});
  26. console.log('client [%s] connected', client_uuid);
  27. var connect_message = nickname + " 来了";
  28. wsSend("notification", client_uuid, nickname, connect_message,clients.length);
  29. ws.on('message', function(message) {
  30. if(message.indexOf('/nick') === 0) {
  31. var nickname_array = message.split(' ');
  32. if(nickname_array.length >= 2) {
  33. var old_nickname = nickname;
  34. nickname = nickname_array[1];
  35. var nickname_message = "用户 " + old_nickname + " 改名为: " + nickname;
  36. wsSend("nick_update", client_uuid, nickname, nickname_message,clients.length);
  37. }
  38. } else {
  39. wsSend("message", client_uuid, nickname, message,clients.length);
  40. }
  41. });
  42. var closeSocket = function(customMessage) {
  43. for(var i=0; i<clients.length; i++) {
  44. if(clients[i].id == client_uuid) {
  45. var disconnect_message;
  46. if(customMessage) {
  47. disconnect_message = customMessage;
  48. } else {
  49. disconnect_message = nickname + " 走了";
  50. }
  51. clients.splice(i, 1);
  52. wsSend("notification", client_uuid, nickname, disconnect_message,clients.length);
  53. }
  54. }
  55. }
  56. ws.on('close', function() {
  57. closeSocket();
  58. });
  59. process.on('SIGINT', function() {
  60. console.log("Closing things");
  61. closeSocket('Server has disconnected');
  62. process.exit();
  63. });
  64. });

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

WebSocket入门教程(五)-- WebSocket实例:简单多人聊天室的更多相关文章

  1. Spring WebSocket初探2 (Spring WebSocket入门教程)<转>

    See more: Spring WebSocket reference整个例子属于WiseMenuFrameWork的一部分,可以将整个项目Clone下来,如果朋友们有需求,我可以整理一个独立的de ...

  2. PySide——Python图形化界面入门教程(五)

    PySide——Python图形化界面入门教程(五) ——QListWidget 翻译自:http://pythoncentral.io/pyside-pyqt-tutorial-the-qlistw ...

  3. Elasticsearch入门教程(五):Elasticsearch查询(一)

    原文:Elasticsearch入门教程(五):Elasticsearch查询(一) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  4. RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)

    原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

  5. 无废话ExtJs 入门教程五[文本框:TextField]

    无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: ...

  6. 转:Scrapy安装、爬虫入门教程、爬虫实例(豆瓣电影爬虫)

    Scrapy在window上的安装教程见下面的链接:Scrapy安装教程 上述安装教程已实践,可行.(本来打算在ubuntu上安装Scrapy的,但是Ubuntu 磁盘空间太少了,还没扩展磁盘空间,所 ...

  7. Scrapy安装、爬虫入门教程、爬虫实例(豆瓣电影爬虫)

    Scrapy在window上的安装教程见下面的链接:Scrapy安装教程 上述安装教程已实践,可行.(本来打算在ubuntu上安装Scrapy的,但是Ubuntu 磁盘空间太少了,还没扩展磁盘空间,所 ...

  8. vue教程2-04 vue实例简单方法

    vue教程2-04 vue实例简单方法 vue实例简单方法: vm.$el -> 就是元素 vm.$data -> 就是data <!DOCTYPE html> <htm ...

  9. 使用Servlet和JSP实现一个简单的Web聊天室系统

    1 问题描述                                                利用Java EE相关技术实现一个简单的Web聊天室系统,具体要求如下. (1)编写一个登录 ...

随机推荐

  1. windows磁盘API实践

    API的列表如下,网上找的,我觉得还是蛮详细的: 磁盘和驱动器管理APIGetLogicalDrivers       获取主机中所有的逻辑驱动器,以BitMap的形式返回.GetLogicalDri ...

  2. Eclipse Debug 使用

      Eclipse的debug模式:代码调试 * Eclipse或MyEclipse就是java的开发工具 * Eclipse开源的.免费的Java开发工具 * MyEclipse基于Eclipse开 ...

  3. wps标准格式

  4. C# nosql之redis初体验

    Redis官方是不支持windows的,只是 Microsoft Open Tech group 在 GitHub上开发了一个Win64的版本,项目地址是: https://github.com/MS ...

  5. photoshop 动作 自己定义快捷键 播放选定的动作

    今天在制作一组效果图.要用到动作.而且是同一个动作,便在网上寻找"播放选定的动作"就是那个三角形播放button的快捷键. 预期这样会大大加快制作过程. 首先制作好动作. 然后,在 ...

  6. python 去掉字符串的 "

    list_name = ["hello", "岚", "许言午", "公司", "赵六", &quo ...

  7. Asp.net2.0里的SessionPageStatePersister

    备注: ASP.NET 页可在处理和提供任何网页所必需的原本无状态 HTTP 请求与响应之间存储 Page 状态信息.此状态称为“视图状态”. ASP.NET 的默认持久性机制是使用 HiddenFi ...

  8. unity, access sprite of UGUI Image

    首先需要using UnityEngine.UI; 然后调用下面语句就不报错了: Image.GetComponent<Image>().sprite 参考:http://answers. ...

  9. Android实现微信自己主动抢红包的程序

    简单实现了微信自己主动抢红包的服务,原理就是依据keyword找到对应的View, 然后自己主动点击.主要是用到AccessibilityService这个辅助服务,基本能够满足自己主动抢红包的功能, ...

  10. Windows虚拟环境下安装mysql-python

    因为在虚拟环境下安装mysql-python走了许多弯路,特此记录,也希望以后的朋友避免像我一样,被环境配置问题搞的半死 直接使用pip安装mysql-python会报错 pip install My ...