nodejs实如今线群聊
这不是一个项目而是一个适合刚開始学习的人学习的样例。主要实现了下面基本功能:
1:群聊。每个人都能够收到其它人的消息,以及能够发消息给其它人,每个人用ip地址标识。
2:显示当前在线用户。
3:每个用户登入登出。其它人都能够看到。
4:每个用户能够看到其它人是否正在输入消息。
实现方式没有选择低效的轮询方式,而是採用基于websocket协议的socket.io模块,websocket协议同意在client与服务端之间建立一个全双工的通信通道。因此服务端能够主动推消息给client。相比传统的轮询,实时性更好。
前端代码例如以下:
- <!doctype html>
- <html>
- <head>
- <title>Socket.IO chat</title>
- <style>
- * { margin: 0; padding: 0; box-sizing: border-box; }
- body { font: 13px Helvetica, Arial; }
- form { background: #fc5bff; padding: 2px; position: fixed; bottom: 0; width: 100%; }
- form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
- form button { width: 9%; background: rgb(217, 222, 221); border: none; padding: 10px; }
- #messages { list-style-type: none; margin: 0; padding: 0; }
- #messages li { padding: 5px 10px; }
- #messages li:nth-child(odd) { background: #eee; }
- </style>
- </head>
- <body>
- <ul id="messages"></ul>
- <ul><li id='typingshow'></li></ul>
- <div id='joinshow'></div>
- <div id='leftshow'></div>
- <div id='onlineshow'></div>
- <form action="">
- <input id="m" autocomplete="off" /><button id='btn'>Send</button>
- </form>
- <script src="jquery-1.10.2.min.js"></script>
- <script src="/socket.io/socket.io.js"></script>
- <script>
- var socket = io();
- var typingIps={};
- var typing=false;
- var lastTypingTime;
- function updateTyping() {
- if (!typing) {
- typing = true;
- socket.emit('typing');
- }
- lastTypingTime = (new Date()).getTime();
- setTimeout(function () {
- var typingTimer = (new Date()).getTime();
- var timeDiff = typingTimer - lastTypingTime;
- if (timeDiff >= 400 && typing) {
- socket.emit('stop typing');
- typing = false;
- }
- }, 400);
- }
- $('form').submit(function(){
- socket.emit('chat message',$('#m').val());
- socket.emit('stop typing');
- typing = false;
- $('#m').val('');
- return false;
- });
- $('#m').keyup(function(){
- updateTyping();
- });
- socket.on('online num',function(msg){
- $('#onlineshow').text('当前在线'+msg+'人');
- });
- socket.on('join', function (msg) {
- $('#joinshow').text(msg.ip+'增加');
- });
- socket.on('typing',function(msg){
- typingIps[msg.ip]=msg.ip;
- var typingArr=[];
- for(var ip in typingIps){
- typingArr.push(typingIps[ip]);
- }
- $('#typingshow').text(typingArr.join(',') + '正在输入...');
- });
- socket.on('stop typing',function(msg){
- delete typingIps[msg.ip];
- var typingArr=[];
- for(var ip in typingIps){
- typingArr.push(typingIps[ip]);
- }
- if(typingArr.length===0){
- $('#typingshow').text('');
- }else{
- $('#typingshow').text(typingArr.join(',') + '正在输入...');
- }
- });
- socket.on('chat message', function(msg){
- $('#messages').append($('<li>').text(msg.ip+'说:'+msg.content));
- });
- socket.on('user left', function(msg){
- $('#leftshow').text(msg.ip+'离开了');
- $('#onlineshow').text('当前在线'+msg.onlineNum+'人');
- });
- </script>
- </body>
- </html>
服务端代码:
- /**
- * Created by luzhen on 14-11-10.
- */
- var express = require('express');
- var app=express();
- var http = require('http').Server(app);
- var io = require('socket.io')(http);
- var ips={};
- app.use(express.static(__dirname + '/public'));
- app.get('/', function (req, res) {
- res.sendFile(__dirname + '/index.html');
- });
- var onlineNum=0;
- io.on('connection', function (socket) {
- console.log(socket.request.connection.remoteAddress);
- ips[socket.request.connection.remoteAddress]=socket.request.connection.remoteAddress;//clientip
- //socket.handshake.address 服务端ip
- onlineNum++;
- socket.broadcast.emit('join', {'ip':socket.request.connection.remoteAddress});//广播新用户增加
- io.emit('online num',onlineNum);//广播当前在线人数
- socket.on('chat message', function (msg) {
- io.emit('chat message', {ip:socket.request.connection.remoteAddress,'content':msg});
- console.log('message: ' + msg);
- });
- socket.on('typing', function (msg) {
- socket.broadcast.emit('typing', {'ip':socket.request.connection.remoteAddress});
- });
- socket.on('stop typing', function (msg) {
- socket.broadcast.emit('stop typing', {'ip':socket.request.connection.remoteAddress});
- });
- socket.on('disconnect',function(){
- delete ips[socket.request.connection.remoteAddress];
- onlineNum--;
- socket.broadcast.emit('user left', {'ip':socket.request.connection.remoteAddress,'onlineNum':onlineNum});
- });
- });
- http.listen(3000, function () {
- console.log('listening on *:3000');
- });
新增了防止刷屏功能,完整代码开源在GitHub上。
Demo演示 查看效果
nodejs实如今线群聊的更多相关文章
- 怎样实如今Windows下编写的代码,直接在Linux下编译
方法一: 怎样实如今Windows7下编写Linux程序.写完程序以后.不用复制文件,直接在Linux(RHEL6.5)机器上编译最新的代码. 1.首先将Windows的代码目录设置为共享目录: 2. ...
- socket.io实现在线群聊
我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单的聊天程序.最最开始 先安装socket.io: npm install socket.io 利用Node的搭 ...
- @font-face(css3属性)实如今网页中嵌入随意字体
@font-face语法规则 @font-face { font-family: <YourWebFontName>; src: <source> [<format> ...
- WebView调用有道词典实如今线查词
WebView(网络视图)能载入显示网页,能够将其视为一个浏览器.它使用了WebKit渲染引擎载入显示网页,用法非常easy,直接在XML文件里写入webview控件就可以,主要代码例如以下: ...
- Android使用有道翻译API实如今线翻译功能
在Android应用中,加入在线翻译的功能,这里调用的是有道翻译的API. 使用有道翻译API.首先要申请一个key,申请地址为:path=data-mode">有道翻译API申请地址 ...
- NodeJS系列~第四个小例子,NodeJs处理Get请求和Post请求
返回目录 说在前 对于HTTP请求来说,我们通常使用的是Get和Post,除此之外还有put,delete等,而对于get来说,比较lightweight,只是对字符串的传输,它会被添加到URL地址里 ...
- nodejs具体解释
文件夹 javascript与node.js javascript与你 因为javascript真正意义上有两种,甚至能够说是三种形态(从最早的作为DHTML进行增强的小工具,到像jQ ...
- 开源server软件
Java缓存server jmemcached http://www.oschina.net/p/jmemcached jmemcached 是一个Java版的 memcached 缓存server, ...
- Android面试题收集(有具体答案)
Android面试题目及其答案 1.Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念 DVM指dalivk的虚拟机.每个Android应用程序都在它自己的进程中执行,都 ...
随机推荐
- eclipse在linux下无故闪退解决
A fatal error has been detected by the Java Runtime Environment: SIGSEGV (0xb) at pc=0x00007f25d0b92 ...
- Java学习之路(3)
JKD的安装和配置: 一.适合超级菜鸟的,不用设置系统路径,不用到处找插件 (1)如果你的系统是windows或linux,根据系统的不同(32位和64位之分),先到www.baidu.com搜索jd ...
- linux解决无法打开资源管理器
前两天升级系统,使用命令pacman -Syyu,大概是使用的是testing缘故,今天发现dolphin无法打开了,使用命令行打开,提示ldmp.so有问题. 解决方法如下: 一,使用命令:pacm ...
- 转载——Java与WCF交互(二):WCF客户端调用Java Web Service
在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttp ...
- UITextView只能显示两行问题
需求:UITextView只能显示两行 UITextView * textView = [[UITextView alloc]init]; textView.frame = CGRectMake(20 ...
- 洛谷 P2863 [USACO06JAN]牛的舞会The Cow Prom-强连通分量(Tarjan)
本来分好组之后,就确定好了每个人要学什么,我去学数据结构啊. 因为前一段时间遇到一道题是用Lca写的,不会,就去学. 然后发现Lca分为在线算法和离线算法,在线算法有含RMQ的ST算法,前面的博客也写 ...
- python-urllib/urllib2模块
urllib与urllib2: urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL.这意味着,你不可以伪装你的User Agent字符串等. ...
- 长安大学第四届“迎新杯”程序设计竞赛 F 打铁的箱子【数学/进制思维/折半枚举】
题目描述 作为彩虹岛上最擅长打铁的人,
- java文件下载导出
前台代码: $("#btnExport").click(function(){ top.$.jBox.confirm("确认要导出房屋信息吗?","系 ...
- [置顶]
一个简单好用的zabbix告警信息发送工具
之前使用邮件和短信发送zabbix告警信息,但告警信息无法实时查看或者无法发送,故障无法及时通知运维人员. 后来使用第三方微信接口发送信息,愉快地用了一年多,突然收费了. zabbix告警一直是我的痛 ...