从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-socketio-chat/

前言

网络聊天室在web1.0的时代就出现了,但当时技术支持比较有限,大都是通过浏览器插件BHO,JavaApplet,Flash实现的。如今HTML5技术风起云涌,通过websocket实现的网络聊天室,被定义为websocket的第一个实验,就像Hello World一样的简单。

今天我也动手完成了这个实验,感觉真的很爽!

目录

  1. socket.io介绍
  2. 服务器端和客户端通信设计
  3. 服务器端实现
  4. 客户端实现
  5. 完整案例代码

1. socket.io介绍

socket.io一个是基于Nodejs架构体系的,支持websocket的协议用于时时通信的一个软件包。socket.io 给跨浏览器构建实时应用提供了完整的封装,socket.io完全由javascript实现。

基于Nodejs实现webscoket其他的框架,请参考文章:Nodejs实现websocket的4种方式

2. 服务器端和客户端通信设计

上图中client1 和 server 描述通信过程,client2描述对其他的客户端,通过广播进行消息通信。

  1. client1向server发起连接请求
  2. server接受client的连接
  3. client1输入登陆用户名
  4. server返回欢迎语
  5. server通过广播告诉其他在线的用户,client1已登陆
  6. client1发送聊天信息
  7. server返回聊天信息(可省略)
  8. server通过广播告诉其他在线的用户,client1的聊天消息
  9. client1关闭连接,退出登陆
  10. server通过广播告诉其他在线的用户,client1已退出

我们看一下测试截图:

  1. 左边: aaa 登陆
  2. 右边: bbb 登陆
  3. 左边: aaa 收到 bbb登陆欢迎消息
  4. aaa 和 bbb 实现对话
  5. 右边: bbb 刷新浏览自动退出
  6. 左边: aaa 收到 bbb的退出消息
  7. 右边: CCC 登陆
  8. 左边: aaa 收到 CCC 登陆欢迎消息
  9. aaa 和 CCC 实现对话

3. 服务器端实现

我们这里使用socket.io和express3的混合模式,让HTTP请求和WebSocket请求都使用3000端口。

服务器端实现,只有一个核心文件app.js。


  1. //引入程序包
  2. var express = require('express')
  3. , path = require('path')
  4. , app = express()
  5. , server = require('http').createServer(app)
  6. , io = require('socket.io').listen(server);
  7. //设置日志级别
  8. io.set('log level', 1);
  9. //WebSocket连接监听
  10. io.on('connection', function (socket) {
  11. socket.emit('open');//通知客户端已连接
  12. // 打印握手信息
  13. // console.log(socket.handshake);
  14. // 构造客户端对象
  15. var client = {
  16. socket:socket,
  17. name:false,
  18. color:getColor()
  19. }
  20. // 对message事件的监听
  21. socket.on('message', function(msg){
  22. var obj = {time:getTime(),color:client.color};
  23. // 判断是不是第一次连接,以第一条消息作为用户名
  24. if(!client.name){
  25. client.name = msg;
  26. obj['text']=client.name;
  27. obj['author']='System';
  28. obj['type']='welcome';
  29. console.log(client.name + ' login');
  30. //返回欢迎语
  31. socket.emit('system',obj);
  32. //广播新用户已登陆
  33. socket.broadcast.emit('system',obj);
  34. }else{
  35. //如果不是第一次的连接,正常的聊天消息
  36. obj['text']=msg;
  37. obj['author']=client.name;
  38. obj['type']='message';
  39. console.log(client.name + ' say: ' + msg);
  40. // 返回消息(可以省略)
  41. socket.emit('message',obj);
  42. // 广播向其他用户发消息
  43. socket.broadcast.emit('message',obj);
  44. }
  45. });
  46. //监听出退事件
  47. socket.on('disconnect', function () {
  48. var obj = {
  49. time:getTime(),
  50. color:client.color,
  51. author:'System',
  52. text:client.name,
  53. type:'disconnect'
  54. };
  55. // 广播用户已退出
  56. socket.broadcast.emit('system',obj);
  57. console.log(client.name + 'Disconnect');
  58. });
  59. });
  60. //express基本配置
  61. app.configure(function(){
  62. app.set('port', process.env.PORT || 3000);
  63. app.set('views', __dirname + '/views');
  64. app.use(express.favicon());
  65. app.use(express.logger('dev'));
  66. app.use(express.bodyParser());
  67. app.use(express.methodOverride());
  68. app.use(app.router);
  69. app.use(express.static(path.join(__dirname, 'public')));
  70. });
  71. app.configure('development', function(){
  72. app.use(express.errorHandler());
  73. });
  74. // 指定webscoket的客户端的html文件
  75. app.get('/', function(req, res){
  76. res.sendfile('views/chat.html');
  77. });
  78. server.listen(app.get('port'), function(){
  79. console.log("Express server listening on port " + app.get('port'));
  80. });
  81. var getTime=function(){
  82. var date = new Date();
  83. return date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
  84. }
  85. var getColor=function(){
  86. var colors = ['aliceblue','antiquewhite','aqua','aquamarine','pink','red','green',
  87. 'orange','blue','blueviolet','brown','burlywood','cadetblue'];
  88. return colors[Math.round(Math.random() * 10000 % colors.length)];
  89. }

4. 客户端实现

这里我们需要定义几个文件:chat.html, chat.js, jquery.min.js, main.css

1). views/chat.html


  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Socket.io - Simple chat</title>
  6. <link rel="stylesheet" type="text/css" href="css/main.css">
  7. <script src="javascripts/jquery.min.js"></script>
  8. <script src="/socket.io/socket.io.js"></script>
  9. <script src="javascripts/chat.js"></script>
  10. </head>
  11. <body>
  12. <h1>Socket.io - Simple chat room</h1>
  13. <div>
  14. <span id="status">Connecting...</span>
  15. <input type="text" id="input"/>
  16. </div>
  17. <div id="content"></div>
  18. </body>
  19. </html>

2). public/javascript/chat.js


  1. $(function () {
  2. var content = $('#content');
  3. var status = $('#status');
  4. var input = $('#input');
  5. var myName = false;
  6. //建立websocket连接
  7. socket = io.connect('http://localhost:3000');
  8. //收到server的连接确认
  9. socket.on('open',function(){
  10. status.text('Choose a name:');
  11. });
  12. //监听system事件,判断welcome或者disconnect,打印系统消息信息
  13. socket.on('system',function(json){
  14. var p = '';
  15. if (json.type === 'welcome'){
  16. if(myName==json.text) status.text(myName + ': ').css('color', json.color);
  17. p = '<p style="background:'+json.color+'">system @ '+ json.time+ ' : Welcome ' + json.text +'</p>';
  18. }else if(json.type == 'disconnect'){
  19. p = '<p style="background:'+json.color+'">system @ '+ json.time+ ' : Bye ' + json.text +'</p>';
  20. }
  21. content.prepend(p);
  22. });
  23. //监听message事件,打印消息信息
  24. socket.on('message',function(json){
  25. var p = '<p><span style="color:'+json.color+';">' + json.author+'</span> @ '+ json.time+ ' : '+json.text+'</p>';
  26. content.prepend(p);
  27. });
  28. //通过“回车”提交聊天信息
  29. input.keydown(function(e) {
  30. if (e.keyCode === 13) {
  31. var msg = $(this).val();
  32. if (!msg) return;
  33. socket.send(msg);
  34. $(this).val('');
  35. if (myName === false) {
  36. myName = msg;
  37. }
  38. }
  39. });
  40. });

3). public/javascript/jquery.min.js
从jquery官方下载: http://jquery.com/

4). public/css/main.css


  1. * {padding:0px; margin:0px;}
  2. body{font-family:tahoma; font-size:12px;margin:10px;}
  3. p {line-height:18px;padding:2px;}
  4. div {width:500px;}
  5. #content {
  6. padding:5px;
  7. background:#ddd;
  8. border-radius:5px;
  9. border:1px solid #CCC;
  10. margin-top:10px;
  11. }
  12. #input {
  13. border-radius:2px;
  14. border:1px solid #ccc;
  15. margin-top:10px;
  16. padding:5px;
  17. width:380px;
  18. }
  19. #status {
  20. width:100px;
  21. display:block;
  22. float:left;
  23. margin-top:15px;
  24. }

5. 完整案例代码

项目已经上传到github: https://github.com/bsspirit/chat-websocket

下载,安装,启动服务器


  1. git clone https://github.com/bsspirit/chat-websocket.git
  2. npm install
  3. node app.js

打开浏览器
可以多打开几个窗口,模拟不同用户有的对话。

http://localhost:3000

做完实验,感觉棒极了。技术创新的革命!!

转载请注明出处:
http://blog.fens.me/nodejs-socketio-chat/

Socket.io在线聊天室的更多相关文章

  1. 使用 Socket.IO 开发聊天室

    前言 Socket.IO 是一个用来实现实时双向通信的框架,其本质是基于 WebSocket 技术. 我们首先来聊聊 WebSocket 技术,先设想这么一个场景: · 用户小A,打开了某个网站的充值 ...

  2. 使用socket.io搭建聊天室

    最近在学习nodejs,需要找一些项目练练手.找来找去发现了一个聊天室的教程,足够简单,也能从中学到一些东西.下面记录我练习过程中待一些笔记. nodeJS模块 共用到了2个模块,express和so ...

  3. node.js + socket.io实现聊天室一

    前段时间,公司打算在社区做一个聊天室.决定让我来做.本小白第一次做聊天类功能,当时还想着通过ajax请求来实现.经过经理提示,说试试当前流行的node.js 和socket.io来做.于是就上网学习研 ...

  4. Socket.io官方聊天室DEMO的学习笔记

    照着Socket.io官方的聊天室代码敲了一遍,遇到了一个奇怪的问题: 每次点击SEND按钮的时候,都会重新刷新页面. 在点击页面的一瞬间,看到了正在加载jquery的提示, 然后以为是jquery用 ...

  5. 使用nodejs引用socket.io做聊天室

    Server: var app = require('http').createServer(handler) , io = require('socket.io').listen(app) , fs ...

  6. node express+socket.io实现聊天室

    参照网址:https://www.jb51.net/article/135058.htm https://www.cnblogs.com/limitcode/p/7845168.html https: ...

  7. 基于 NodeJs 打造 Web 在线聊天室

    Socket.IO 简介与基础环境搭建 任务时间:10min ~ 20min 关于 Socket.IO Socket.IO 可以实现在浏览器和服务器之间实时双向通信,本节课程将详细介绍 Socket. ...

  8. AngularJS+Node.js+socket.io 开发在线聊天室

    所有文章搬运自我的个人主页:sheilasun.me 不得不说,上手AngularJS比我想象得难多了,把官网提供的PhoneCat例子看完,又跑到慕课网把大漠穷秋的AngularJS实战系列看了一遍 ...

  9. 百度前端面试题-类似slack的在线聊天室

    别人国庆出去玩,我在家写代码的感觉也是很不错哒. 首先介绍一下技术架构吧! 使用了js框架:FFF,zepto,jquery,md5.min.js 前端框架:Bootstrap 后端:野狗,部分PHP ...

随机推荐

  1. MFC CWnd仿按钮

    CBtn::CBtn() { RegisterWndClass(); } bool CBtn::RegisterWndClass(void) { WNDCLASS n; HINSTANCE hInst ...

  2. Linux学习之第十九、条件判断

    原文地址:http://vbird.dic.ksu.edu.tw/linux_basic/0340bashshell-scripts_4.php 条件判断式 只要讲到『程序』的话,那么条件判断式,亦即 ...

  3. ASP.NET MVC 中将FormCollection与实体间转换方法【转】

    将Action动作中传递的FormCollection转变成对应的实体,可以使用Controller的TryUpdateModel()方法. 示例如下: [HttpPost] public Actio ...

  4. 【POJ 1125】Stockbroker Grapevine

    id=1125">[POJ 1125]Stockbroker Grapevine 最短路 只是这题数据非常水. . 主要想大牛们试试南阳OJ同题 链接例如以下: http://acm. ...

  5. css3设置box-pack和box-align让div里面的元素垂直居中

    只要设置元素的box-pack和box-align即可,这两个属性当前只有webkit和moz支持,要设置垂直居中的话只需要将这两个属性的值都设置为center即可,需要的朋友可以参考下   以前处理 ...

  6. Oracle 字符集问题

    1 简介 ORACLE数据库字符集,即Oracle全球化支持(Globalization Support),或即国家语言支持(NLS)其作用是用本国语言和格式来存储.处理和检索数据.利用全球化支持,O ...

  7. 高效CSS开发核心要点摘录

    做网站的,我们都知道尽量减少请求数,压缩CSS代码量,使用高效CSS选择符等方式可以来提高网站的载入速度和访问速度,也就是优化网站的性能. 下面分析了一些CSS的书写方式,很多都是我们知道并且正在使用 ...

  8. jquery 选择器之children与find

    children()和find() 两个用于向下遍历 DOM 树的 jQuery 方法 children() 方法返回被选元素的所有直接子元素. find() 方法返回被选元素的后代元素,一路向下直到 ...

  9. Scala主构造器、私有构造器、构造器重载

    Scala中的主构造器跟在定义类的时候声明类名之后 如下: class scala(arg : String) { // } private[this] 修饰该字段只能被当前所对应的对象所访问,其他对 ...

  10. PHP之闭包详解

    匿名函数提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它.声明一个匿名函数是这样: $func = function() { }; //带结束符 可以看到 ...