基于socket.io+express实现多房间聊天

socket.io简介

Socket.IO是一个开源的WebSocket库,它通过Node.js实现WebSocket服务端,同时也提供客户端JS库。Socket.IO支持以事件为基础的实时双向通讯,它可以工作在任何平台、浏览器或移动设备。

Socket.IO支持4种协议:WebSocket、htmlfile、xhr-polling、jsonp-polling,它会自动根据浏览器选择适合的通讯方式,从而让开发者可以聚焦到功能的实现而不是平台的兼容性,同时Socket.IO具有不错的稳定性和性能。

多房间聊天

socket.io提供rooms和namespace的API

用rooms的API就可以实现多房间聊天了,总结出来无外乎就是:join/leave room 和 say to room

// join和leave
io.on('connection', function(socket){
 socket.join('some room');
 // socket.leave('some room');
});

// say to room
io.to('some room').emit('some event'):
io.in('some room').emit('some event'):

代码 github
新建文件夹chatapp-demo
chatapp-demo/package.json

{
 "name": "chatapp-demo",
 "version": "1.0.0",
 "description": "multi room chat app demo, powered by socket.io",
 "main": "app.js",
 "dependencies": {
  "express": "^4.13.3",
  "hbs": "^3.1.0",
  "path": "^0.11.14",
  "socket.io": "^1.3.6"
 },
 "devDependencies": {},
 "author": "wuyanxin",
 "license": "ISC"
}

执行 npm install

服务端代码

增加文件 chatapp-demo/app.js

var express = require('express');
var path = require('path');
var IO = require('socket.io');
var router = express.Router();

var app = express();
var server = require('http').Server(app);
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');

// 创建socket服务
var socketIO = IO(server);
// 房间用户名单
var roomInfo = {};

socketIO.on('connection', function (socket) {
 // 获取请求建立socket连接的url
 // 如: http://localhost:3000/room/room_1, roomID为room_1
 var url = socket.request.headers.referer;
 var splited = url.split('/');
 var roomID = splited[splited.length - 1];  // 获取房间ID
 var user = '';

 socket.on('join', function (userName) {
  user = userName;

  // 将用户昵称加入房间名单中
  if (!roomInfo[roomID]) {
   roomInfo[roomID] = [];
  }
  roomInfo[roomID].push(user);

  socket.join(roomID);  // 加入房间
  // 通知房间内人员
  socketIO.to(roomID).emit('sys', user + '加入了房间', roomInfo[roomID]);
  console.log(user + '加入了' + roomID);
 });

 socket.on('leave', function () {
  socket.emit('disconnect');
 });

 socket.on('disconnect', function () {
  // 从房间名单中移除
  var index = roomInfo[roomID].indexOf(user);
  if (index !== -1) {
   roomInfo[roomID].splice(index, 1);
  }

  socket.leave(roomID);  // 退出房间
  socketIO.to(roomID).emit('sys', user + '退出了房间', roomInfo[roomID]);
  console.log(user + '退出了' + roomID);
 });

 // 接收用户消息,发送相应的房间
 socket.on('message', function (msg) {
  // 验证如果用户不在房间内则不给发送
  if (roomInfo[roomID].indexOf(user) === -1) {
   return false;
  }
  socketIO.to(roomID).emit('msg', user, msg);
 });

});

// room page
router.get('/room/:roomID', function (req, res) {
 var roomID = req.params.roomID;

 // 渲染页面数据(见views/room.hbs)
 res.render('room', {
  roomID: roomID,
  users: roomInfo[roomID]
 });
});

app.use('/', router);

server.listen(3000, function () {
 console.log('server listening on port 3000');
});

客户端代码

新增chatapp/views/room.hbs

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>{{roomID}}</title>
 <style>
  #msglog, #messageInput {
   border: 1px solid #ccc;
   width: 500px;
   height: 350px;
   overflow-y: auto;
   font-size: 14px;
  }
  #messageInput {
   height: 80px;
  }
  .message {
   line-height: 22px;
  }
  .message .user {
   padding-right: 5px;
   padding-left: 5px;
   color: brown;
  }
  .sysMsg {
   color: #c1bfbf;
   padding-right: 5px;
   padding-left: 5px;
   font-size: 12px;
  }
  #users {
   width: 490px;
   padding: 0 5px 5px;
  }
 </style>
</head>
<body>
 昵称: <span id="userName"></span> <br/>
 房间: {{roomID}} <br/>
 当前在线人数: <span id="count">{{users.length}}</span> <br/>
 在线用户: <div id="users">{{users}}</div>

 <div id="msglog">

 </div>
 <textarea name="message" id="messageInput"></textarea>
 <br/>
 按Enter键发送
 <button id="joinOrLeave">退出房间</button>

 <script src="/socket.io/socket.io.js"></script>
 <script src="/js/jquery.js"></script>
 <script>
  $(function () {
   // ----------设置昵称-------------
   var userName = '';
   while ($('#userName').text().trim() === '') {
    userName = prompt("请设置你的昵称","");
    $('#userName').text(userName);
   }

   // ---------创建连接-----------
   var socket = io();

   // 加入房间
   socket.on('connect', function () {
    socket.emit('join', userName);
   });

   // 监听消息
   socket.on('msg', function (userName, msg) {
    var message = '' +
      '<div class="message">' +
      ' <span class="user">' + userName + ': </span>' +
      ' <span class="msg">' + msg + '</span>' +
      '</div>';
    $('#msglog').append(message);
    // 滚动条保持最下方
    $('#msglog').scrollTop($('#msglog')[0].scrollHeight);
   });

   // 监听系统消息
   socket.on('sys', function (sysMsg, users) {
    var message = '<div class="sysMsg">' + sysMsg + '</div>';
    $('#msglog').append(message);

    $('#count').text(users.length);
    $('#users').text(users);
   });

   // 发送消息
   $('#messageInput').keydown(function (e) {
    if (e.which === 13) {
     e.preventDefault();
     var msg = $(this).val();
     $(this).val('');

     socket.send(msg);
    }
   });

   // 退出房间
   $('#joinOrLeave').click(function () {
    if ($(this).text() === '退出房间') {
     $(this).text('进入房间');
     socket.emit('leave');
     var msg = '你已经退出了房间,重新发言请点击"进入房间"';
     $('#msglog').append('<div class="sysMsg">'+msg+'</div>');
    } else {
     $(this).text('退出房间');
     socket.emit('join', userName);
    }

   });
  });
 </script>
</body>
</html>

新增 chatapp/public/index.html

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title>demo</title>
</head>
<body>
 欢迎您,骚年

 <div>
  <p>房间列表</p>
  <ul>
   <li id="room_1"><a href="/room/room_1" target="_blank">1号房间</a></li>
   <li id="room_2"><a href="/room/room_2" target="_blank">2号房间</a></li>
   <li id="room_3"><a href="/room/room_3" target="_blank">3号房间</a></li>
   <li id="room_4"><a href="/room/room_4" target="_blank">4号房间</a></li>
   <li id="room_5"><a href="/room/room_5" target="_blank">5号房间</a></li>
   <li id="room_6"><a href="/room/room_6" target="_blank">6号房间</a></li>
   <li id="room_7"><a href="/room/room_7" target="_blank">7号房间</a></li>
   <li id="room_8"><a href="/room/room_8" target="_blank">8号房间</a></li>
   <li id="room_9"><a href="/room/room_9" target="_blank">9号房间</a></li>
   <li id="room_10"><a href="/room/room_10" target="_blank">10号房间</a></li>
  </ul>
 </div>

</body>
</html>

运行效果

代码已放在github https://github.com/wuyanxin/chatapp-demo.git

(0)

相关推荐

  • 基于Nodejs利用socket.io实现多人聊天室

    socket.io简介 在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这篇文章讲述了websocket无到有,根据协议,分析数据帧的头,进行构建websocket.虽然代码短,但可以很好地体现websocket的原理. ,这个特性提供了浏览器端和服务器端的基于TCP连接的双向通道.但是并不是所有的浏览器都支持websocket特性,故为了磨平浏览器间的差异,为开发者提供统一的接口,引入了socket.io模块.在不支持webs

  • 使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室

    一,利用Node搭建静态服务器 这个是这个项目的底层支撑部分.用来支持静态资源文件像html, css, gif, jpg, png, javascript, json, plain text等等静态资源的访问.这里面是有一个mime类型的文件映射. mime.js /** * mime类型的 map * @ author Cheng Liufeng * @ date 2014/8/30 * 当请求静态服务器文件的类型 html, css, gif, jpg, png, javascript,

  • vue + socket.io实现一个简易聊天室示例代码

    vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了.功能虽然不多,但还是有收获.设计和实现思路较为拙劣,恳请各位道友指正. 可以达到的需求 能查看在线用户列表 能发送和接受消息 使用到的框架和库 socket.io做为实时通讯基础 vuex/vue:客户端Ui层使用 Element-ui:客户端Ui组件 类文件关系图 服务端: 客户端: 服

  • Node.js websocket使用socket.io库实现实时聊天室

    认识websocket WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duple).一开始的握手需要借助HTTP请求完成. 其实websocket 并不是很依赖Http协议,它也拥有自己的一套协议机制,但在这里我们需要利用的socket.io 需要依赖到http . 之前用java jsp写过一个聊天,其实实现逻辑并不难,只是大部分时间都用在UI的设计上,其实现原理就是一个基于websocket的通信,要想做一个好的聊天室,我觉得大部

  • socket.io实现在线群聊功能

    我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单的聊天程序.最最开始 先安装socket.io: npm install socket.io 利用Node的搭建Http服务 分为两个文件,服务端文件app.js和客户端index.html app.js var app = require('http').createServer(handler) io = require('socket.io').listen(app) fs = require('fs

  • 基于socket.io+express实现多房间聊天

    socket.io简介 Socket.IO是一个开源的WebSocket库,它通过Node.js实现WebSocket服务端,同时也提供客户端JS库.Socket.IO支持以事件为基础的实时双向通讯,它可以工作在任何平台.浏览器或移动设备. Socket.IO支持4种协议:WebSocket.htmlfile.xhr-polling.jsonp-polling,它会自动根据浏览器选择适合的通讯方式,从而让开发者可以聚焦到功能的实现而不是平台的兼容性,同时Socket.IO具有不错的稳定性和性能.

  • 基于Socket.IO实现Android聊天功能代码示例

    一.简述 Socket.IO是一个完全由JavaScript实现.基于Node.js.支持WebSocket的协议用于实时通信.跨平台的开源框架,它包括了客户端的JavaScript和服务器端的Node.js. 该种官方介绍看起来有点懵逼,简而言之就是:客户端可通过Socket.IO与服务器建立实时通信管道 二.应用 该下就是介绍Socket.IO通信管道的铺设.通信以及销毁工作. 2.1 引入Socket.io包 compile 'io.socket:socket.io-client:0.8.

  • Android基于socket实现的简单C/S聊天通信功能

    本文实例讲述了Android基于socket实现的简单C/S聊天通信功能.分享给大家供大家参考,具体如下: 主要想法:在客户端上发送一条信息,在后台开辟一个线程充当服务端,收到消息就立即回馈给客户端. 第一步:创建一个继续Activity的SocketClientActity类,包为com.pku.net 编写布局文件socketclient.xml,代码如下: <?xml version="1.0" encoding="utf-8"?> <Lin

  • 基于socket.io和node.js搭建即时通信系统

    使用socket.io和nodejs搭建websocket服务器端 socket.io不仅可以搭建客户端的websocket服务,而且支持nodejs服务器端的websocket. 下面让我来介绍一下怎么安装配置nodejs. 进入http://nodejs.org/#download下载msi文件.一直点next安装.最后文件会自动安装在C:\nodejs目录下. 安装完成后,会自动配置环境环境变量.如果没有自动配置,自己手动在path处加上 ;C:\nodejs\. 安装完成后,需要配置np

  • vue+socket.io+express+mongodb 实现简易多房间在线群聊示例

    项目简介 主要是通过做一个多人在线多房间群聊的小项目.来练手全栈技术的结合运用. 项目源码:chat-vue-node 主要技术: vue2全家桶 + socket.io + node(express) + mongodb(mongoose) 环境配置: 需安装配置好 node,mongodb环境(参考:http://www.jb51.net/article/109449.htm); 建议安装 Robomogo 客户端来管理mongodb数据. 编译运行: 1.开启MongoDB服务,新建命令行

  • node.js + socket.io 实现点对点随机匹配聊天

    真心佩服那些可以经常发布笔记的人,其实我也想经常发来的,奈何技术不够加上懒,要向大神们多多学习了,前段时间有用bomb平台自带的socket写一个聊天室,其实基本就是改了改它的demo,这次想实现一个随机私聊,所以自己基于node 和 socket.io 来搭服务,当然,第一次用node做东西玩,虽然做的不好,但是也蛮分享下哈. 先说说用到的东西, node 用来做后台服务,express 用来托管静态资源,然后socket.io 用来传送聊天数据.接下来说说思路,其实用socket.io来传数

  • node.js基于socket.io快速实现一个实时通讯应用

    随着web技术的发展,使用场景和需求也越来越复杂,客户端不再满足于简单的请求得到状态的需求.实时通讯越来越多应用于各个领域. HTTP是最常用的客户端与服务端的通信技术,但是HTTP通信只能由客户端发起,无法及时获取服务端的数据改变.只能依靠定期轮询来获取最新的状态.时效性无法保证,同时更多的请求也会增加服务器的负担. WebSocket技术应运而生. WebSocket概念 不同于HTTP半双工协议,WebSocket是基于TCP 连接的全双工协议,支持客户端服务端双向通信. WebSocke

  • C++基于socket UDP网络编程实现简单聊天室功能

    本文实例为大家分享了C++基于socket UDP实现简单聊天室功能的具体代码,供大家参考,具体内容如下 0.通信步骤流程图 (左:服务器:右:客户端:) 1.服务器代码 1.1服务器类头文件(CServer_UDP.h) #pragma once #include <winsock2.h> class CServer_UDP { public: CServer_UDP(); void SendMsg(const char sendBuf[]); void RecMsg(); ~CServer

  • Java基于Socket实现多人聊天室

    本文实例为大家分享了Java基于Socket实现简易版多人聊天室的具体代码,供大家参考,具体内容如下 一. 聊天室需求 1.一个服务端,多个客户端:2.实现客户端和服务端的交互:3.客户端发送信息,服务端收到信息,再转发给其他客户端:4.上下线时显示哪个客户端上下线并且显示在线客户端数量: 二.代码分析 1. 建立连接 客户端类,创建发送端Socket对象,用自己的IP地址和端口号,与服务端建立连接. class Client: //用于与服务端通信的Socket private Socket

随机推荐