接触Socket.IO
由于项目需求,要实现消息推送的功能,之前也很少接触Socket,
需求也相对简单,以前是信息是客户端的主动拉取,现在我们要是做到服务推送,如何实现呢??
看了不少资料考虑过MQ(ActiveMQ、RabbitMQ、RocketMQ、kafka)但由于时间和精力问题也没研究明白(晚些在研究一下哈!!)
后来无意间看到了个Socket.IO,觉得这个可行,上手快,相对来说使用起来也没那么复杂;
什么是Socket.IO
socket.io是一个跨浏览器支持WebSocket的实时通讯的JS。
WebSocket是HTML5新增的一种通信协议,其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
Socket.io支持及时、双向、基于事件的交流,可在不同平台、浏览器、设备上工作,可靠性和速度稳定。最典型的应用场景如:
- 实时分析:将数据推送到客户端。
- 实时通讯:聊天应用。
- 二进制流传输:socket.io支持任何形式的二进制文件传输,例如图片、视频、音频等。
- 文档合并:允许多个用户同时编辑一个文档,并能够看到每个用户做出的修改。
Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,会根据情况选择方法来进行通讯。
好的这完全满足我们现在的需求了,实现服务器向客户端推动消息\数据。也可以定向推动消息(就它了)。
使用Scoket.IO (参考:从0开始用Nodejs做一个聊天室)
看一下实现效果:
服务端
客户端:http://localhost:3000/ (由于是本地测试DEMO,所以你懂的)
1、用户名为1(用户界面):
2、用户名2(用户界面)
一看页面也许大家就蒙了:这不是聊天室吗,对它就是一个聊天室,可消息推送又何尝不是一个聊天室内?
聊天室:双向通信;
我们的需求消息推送:客户端被动的接受数据(所谓的消费者)聆听者,服务器一个在哪嘚不嘚的,其他客户端在哪听着,太像给技术部的家伙们开会了;
- 安装NodeJS(不多说,直接上链接)
- 创建项目目录,如(C:\lTS_DEMO)创建服务器(server.js)、创建客户端(index.html)
- CMD 项目目录 安装socke.io npm install --save socket.io
- 编写代码
1 var app = require('express')(); 2 var http = require('http').Server(app); 3 var io = require('socket.io')(http); 4 const schedule = require('node-schedule'); 5 var _ =require('underscore'); 6 7 var usocket = []; 8 9 app.get('/', function(req, res){ 10 res.sendFile(__dirname + '/index.html'); 11 }); 12 13 io.on('connection', function(socket){ 14 15 socket.on("join", function (name) { 16 usocket[name] = socket 17 io.emit("join", name) 18 console.log('用户上线:' +name+"---"+socket.id) 19 }) 20 21 socket.on('disconnect',function(){ 22 console.log('用户下线: '+socket.id); 23 io.emit("public","下线通知:"+socket.id+"用户下线"); 24 }) 25 26 socket.on("message", function (msg) { 27 io.emit("message", msg) //将新消息广播出去 28 }) 29 30 socket.on("public", function (msg) { 31 io.emit("public", msg) //将新消息广播出去 32 33 }) 34 35 }); 36 /* 37 const scheduleCronstyle = ()=>{ 38 //每分钟的第30秒定时执行一次: 39 schedule.scheduleJob('30 * * * * *',()=>{ 40 io.emit("public","公告:"+'scheduleCronstyle:' + new Date()); 41 if(toSocket = usocket['1']){ 42 toSocket.emit('other','只发给你用户1'); 43 } 44 if(toSocket = usocket['2']) 45 { 46 toSocket.emit('other','只发给你用户2'); 47 } 48 49 });} 50 scheduleCronstyle(); 51 */ 52 53 http.listen(3000, function() { 54 console.log('listening on *:3000'); 55 });
1 <!doctype html> 2 <html> 3 <head> 4 <title>Socket.IO chat</title> 5 <style> 6 * { margin: 0; padding: 0; box-sizing: border-box; } 7 body { font: 13px Helvetica, Arial; } 8 form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } 9 form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } 10 form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } 11 #messages { list-style-type: none; margin: 0; padding: 0; } 12 #messages li { padding: 5px 10px; } 13 #messages li:nth-child(odd) { background: #eee; } 14 </style> 15 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> 16 </head> 17 <body> 18 <ul id="messages"></ul> 19 <ul id="pubilic" style="background-color:gray"></ul> 20 <form action=""> 21 <input id="m" autocomplete="off" /><button>发送</button> 22 </form> 23 </body> 24 25 <script src="/socket.io/socket.io.js"></script> 26 <script> 27 var name = prompt("请输入你的昵称:"); 28 var socket = io() 29 30 //发送昵称给后端,并更改网页title 31 socket.emit("join", name) 32 document.title = name + "的群聊" 33 34 socket.on("join", function (user) { 35 addLine(user + " 加入了群聊") 36 }) 37 socket.on('offline', function (data) { 38 //显示系统消息 39 var sys = '<div style="color:#f00">系统('+now()+'):'+'用户 '+data.name+' 下线了!</div>'; 40 $("#messages").append(sys+"<br/>"); 41 }) 42 43 //接收到服务器发来的message事件 44 socket.on("message", function(msg) { 45 addLine(msg.name+":"+msg.msg) 46 }) 47 socket.on("other", function(msg) { 48 addLine("惊喜:"+":"+msg) 49 }) 50 socket.on("public",function(msg) { 51 addpublicLine(msg) 52 }) 53 function addpublicLine(msg) { 54 $('#pubilic').append($('<li>').text(msg)); 55 } 56 57 //当发送按钮被点击时 58 $('form').submit(function () { 59 var msg = $("#m").val() //获取用户输入的信息 60 var obj={msg:msg,name:name}; 61 socket.emit("message", obj) //将消息发送给服务器 62 $("#m").val("") //置空消息框 63 return false //阻止form提交 64 }) 65 66 function addLine(obj) { 67 $('#messages').append($('<li>').text(obj)); 68 } 69 </script> 70 </html>
其中有以下引用
直接在控制台运行:node server.js 命令
浏览器访问: http://localhost:3000/