Socket.IO 入门


本文来自作者 蓝天  GitChat 上分享 「Socket.IO 入门」,阅读原文查看交流实录。

文末高能

编辑 | 哈比

1. Socket.IO 原理

node.js 提供了高效的服务端运行环境,但是由于浏览器端对 HTML5 的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是 socket.io 诞生。

Socket.io 将 Websocket 和轮询 (Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。

也就是说,Websocket 仅仅是 Socket.io 实现实时通信的一个子集。那么,Socket.io 都实现了 Polling 中的那些通信机制呢?

WebSocket Adobe® Flash® Socket AJAX long polling AJAX multipart streaming Forever Iframe JSONP Polling

Adobe® Flash® Socket 大部分 PC 浏览器都支持的 socket 模式,不过是通过第三方嵌入到浏览器,不在 W3C 规范内,所以可能将逐步被淘汰,况且,大部分的手机浏览器都不支持这种模式。

AJAX long polling 这个很好理解,所有浏览器都支持这种方式,就是定时的向服务器发送请求,缺点是会给服务器带来压力并且出现信息更新不及时的现象。

AJAX multipart streaming  这是在 XMLHttpRequest 对象上使用某些浏览器(比如说 Firefox)支持的 multi-part 标志。

Ajax 请求被发送给服务器端并保持打开状态(挂起状态),每次需要向客户端发送信息,就寻找一个挂起的的 http 请求响应给客户端,并且所有的响应都会通过统一连接来写入。

var xhr = \$.ajaxSettings.xhr(); xhr.multipart =true; xhr.open('GET', 'ajax', true); xhr.onreadystatechange = function() {   if (xhr.readyState == 4) {     processEvents($.parseJSON(xhr.responseText));   } }; xhr.send(null);

Forever Iframe (永存的 Iframe)技术涉及了一个置于页面中的隐藏 Iframe 标签,该标签的 src 属性指向返回服务器端事件的 servlet 路径。 

每次在事件到达时,servlet 写入并刷新一个新的 script 标签,该标签内部带有 JavaScript 代码,iframe 的内容被附加上这一 script 标签,标签中的内容就会得到执行。

这种方式的缺点是接和数据都是由浏览器通过 HTML 标签来处理的,因此你没有办法知道连接何时在哪一端已被 断开了,并且 Iframe 标签在浏览器中将被逐步取消使用。

JSONP Polling  JSONP 轮询基本上与 HTTP 轮询一样,不同之处则是 JSONP 可以发出跨域请求,详细请搜索查询 jsonp 的内容。

2. Socket.IO 环境搭建

本次给大家带来两种使用 Socket.IO 的方法。

两种方法都需要安装 JDK,JDK 版本要求 1.7 以上,JDK 安装方法就不说了,网上有很多

使用 Node.js 运行 Socket.IO

首先我们需要下载 Node.js 并安装。

这次我下载的是 9.2.0 Current 版本。

我安装的目录是——- E:\Program Files\nodejs 这个目录是用来配置环境变量的。安装完成之后我们可以得到如下图这些文件。

这样我们还需要去配置环境变量。新建一个 NODEJS_HOME=E:\Program Files\nodejs。

在 Path 最后追加 %NODEJS_HOME%\

配置完成后我们验证一下 node.js 是否可用。打开 CMD,输入 node -v:

目前我们只是完成了 node.js 的安装。并无法使用 socket.io,因为 socket.io 只是 node.js 下的一个模块,需要我们手动安装。

如何安装呢?很简单。打开 CMD 直接输入 npm install socket.io 就可以自动的从网上把 socketio 下载下来了。

至此我们就将环境搭建完成了。

使用 Node.js 运行 socket.io

为了方便,我直接在桌面新建了一个文件夹 socketIOdemo。目录如下:

app.js 代码如下:

var app = require('http').createServer(handler) , io = require('socket.io').listen(app) , fs = require('fs') app.listen(3000);// 服务器监听的端口号 3000function handler (req, res) { fs.readFile(__dirname + '/index.html',function (err, data) {if (err) { res.writeHead(500);return res.end('Error loading index.html'); } res.writeHead(200); res.end(data); }); }/* 以上是标准写法,无特殊情况不用修改 **//* 下面是开启 socketio 链接监听 **/io.sockets.on('connection', function (socket) {        console.log(" 客户端连接 "); socket.on('message', function (data) {console.log(data);        /* 给所有客户端广播消息 */        io.sockets.emit('chatevent', { userName: data.userName,message:data.message });        /* 给当前客户端广播消息 */        //socket.emit('chatevent', { userName: data.userName,message:data.message });        /* 给除了自己以外的客户端广播消息 *///socket.broadcast.emit('chatevent', { userName: data.userName,message:data.message });}); socket.on('disconnect',function(){console.log(' 客户端断开连接 '); }); });console.log("success listening port:3000");

jquery-3.2.1.min.js 和 socket.io.js 请分别到网上下载。chat.html 代码如下:

  <!DOCTYPE html>

<html><head>    <meta http-equiv="Content-Type" content="text/html;" charset="UTF-8">    <title>Socketio chat</title>    <script src="./js/jquery-3.2.1.min.js" type="text/javascript"></script>    <script type="text/javascript" src="./js/socket.io.js"></script>    <style>      body {          padding: 20px;      }      #console {          height: 400px;          overflow: auto;      }      .username-msg {          color: orange;      }      .connect-msg {          color: green;      }      .disconnect-msg {          color: red;      }      .send-msg {          color: #888      }    </style></head><body><h3>Netty-socketio chat demo</h3><br /><div id="console" class="well"></div><form class="well form-inline" onsubmit="return false;">     <input id="name" class="input-xlarge" type="text" placeholder=" 用户名称 . . . " />     <input id="msg" class="input-xlarge" style="width:500px;height:100px;" type="text" placeholder=" 发送内容 . . . " />     <button type="button" onClick="sendMessage()" class="btn"> 发送 </button>     <br /></form></body><script type="text/javascript">     Date.prototype.Format = function (fmt) { //author: meizz         var o = {             "M+": this.getMonth() + 1, // 月份             "d+": this.getDate(), // 日             "h+": this.getHours(), // 小时             "H+": this.getHours(), // 小时             "m+": this.getMinutes(), // 分             "s+": this.getSeconds(), // 秒             "q+": Math.floor((this.getMonth() + 3) / 3), // 季度             "S": this.getMilliseconds() // 毫秒         };         if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));         for (var k in o)             if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));         return fmt;    }    var socket = io.connect('http://localhost:3000');    // 连接服务器成功的监听    socket.on('connect',function() {        output('<span class="connect-msg"> 客户端连接服务器 !</span>');    });    // 接收服务端广播的监听    socket.on('chatevent', function(data) {        output('<span class="username-msg">' + data.userName + ' : </span>'+ data.message);    });    // 断开服务器的监听    socket.on('disconnect',function(data) {        output('<span class="disconnect-msg"> 客户端已断开连接 ! </span>');    });    function sendDisconnect() {    socket.disconnect();    }    function sendReconnect() {    socket.reconnect();    }    /* 点击发送按钮 */    function sendMessage() {        var userName = $("#name").val();        var message = $('#msg').val();        var chatDate = new Date();        $('#msg').val('');        socket.emit('message', {            userName : userName,            message : message        });    }    function output(message) {        var currentTime = "<span class='time' >" + new Date().Format("yyyy-MM-dd HH:mm:ss") + "</span>";        var element = $("<div>" + currentTime + " " + message + "</div>");        $('#console').prepend(element);    }</script></html>

准备工作已经完成,现在我们可以尝试将 socket.io 运行起来。打开 CMD,输入 node “app.js 所在位置\app.js”。我的桌面位置是 C:\Users\minghui\Desktop\。所以我输入的是 node C:\Users\minghui\Desktop\socketIOdemo\js\app.js。

用浏览器打开我们编写的 chat.html。

好了,这个 socket.IO 小程序已经顺利的运行了。

2. 在 java web 程序中使用 socket.io

在 java 端我们使用的是 netty-socketio,是 Socket.IO 在 JAVA 端移植版本。我们可以到这个地址去下载:
https://www.versioneye.com/java/com.corundumstudio.socketio:netty-socketio/1.7.7


我下载的是 netty-socketio-1.7.7.jar。

最后来一张所有 lib 的图:

一定要全部下载并引用,现在我们创建一个 web 项目。

只需要勾选 web 即可,项目名我写的是 socketiodemo,然后 finish。附一张完成的项目图:

现在我们将代码贴上:

ChatBean

App


SocketIOChatListener

SysAuthorizationListener

index.jsp

项目建好了,现在我们可以跑起来试一下。首先我们启动 App.java 里面的 main 方法。

启动成功,现在我们再启动 web 项目,起来之后,我们进入主页。


由于是一个简单的项目,并没有使用数据库,所以也就没有做登陆了,以后整合进项目之后,可以直接用系统的用户名来代替。最后我们来聊天试试效果。

近期热文

接口测试工具 Postman 使用实践

如何基于 Redis 构建应用程序组件

深度学习在摄影技术中的应用与发展

这样做,你的面试成功率将达到 90%

如何用 TensorFlow 让一切看起来更美?

Web 安全:前端攻击 XSS 深入解析

「阅读原文」看交流实录,你想知道的都在这里

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值