由浅及深初探websocket

一、websocket是什么?

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信--允许服务器主动发送信息给客户端。

websocket是HTML5的一个新协议,它允许服务端向客户端传递信息,实现浏览器和客户端双工通信。websocket弥补了HTTP不支持长连接的特点。

WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,附加信息如图所示:

浏览器支持:所有的最新浏览器支持最新WebSocket规范(RFC 6455) ,从维基百科上介绍浏览器对WebSocket的支持如下表所示:

移动端支持:移动端基本都支持websocket了,其实和浏览器版支持的版本一样,具体支持如下所示:

服务器支持:目前主流的web服务器都已经支持,具体版本如下表所示:

美女

那websocket和socket,websocket和http又有什么区别呢?

这个问题问得好,要想知道它们的区别其实并不难,跟着我继续往下看吧。

那月真美

二、websocket与socket和http的区别

HTTP、WebSocket 等应用层协议,都是基于 TCP 协议来传输数据的。我们可以把这些高级协议理解成对 TCP 的封装。

既然大家都使用 TCP 协议,那么大家的连接和断开,都要遵循 TCP 协议中的三次握手和四次握手 ,只是在连接之后发送的内容不同,或者是断开的时间不同。HTTP是短连接,Websocket是长连接。

Socket 其实并不是一个协议。它工作在 OSI 模型会话层(第5层),是为了方便大家直接使用更底层协议(一般是 TCP 或 UDP )而存在的一个抽象层。也就是说Socket其实是一组接口规范。

三、websocket的应用

WebSocket有四个重要的监听方法,分别是连接已建立(onopen)方法,接收消息(onmessage)方法,发生异常(onerror)方法,连接已关闭(onclose)方法。

前端js代码:

var initWs = function(){

var websocket;

if("WebSocket" in window){

websocket = new WebSocket(config.wsUrl+"?userId="+user.userId);

}else{

alert("你的浏览器不支持websocket");

}

var ws = new Ws();

//连接已建立方法

websocket.onopen = function(){

console.log("websocket已连接");

ws.count++;

ChatSendEmptyContent();

};

//接受消息并处理

websocket.onmessage = function(e){

console.log(e);

var data = JSON.parse(e.data);

};

//发生异常方法

websocket.onerror = function(e){

console.log("websocket连接异常:" + e);

};

//连接已关闭方法

websocket.onclose = function(code){

console.log("websocket连接已关闭:" + code);

$("#local_gameover").html("已掉线");

ws.count--;

};

return websocket

}

这个是客户端js代码,调用initWs 方法就能初始化WebSocket,在onmessage 方法里面可以进行自己象要的业务操作,接收initWs 方法的返回值,可以在其它地方调用WebSocket.send()方法发送消息。

后端java代码:

/**

* Created by ZhaoLai Huang on 2018/4/9.

*/

@ServerEndpoint(value = "/websocket")

@Component

public class Websocket {

private final static org.slf4j.Logger logger = LoggerFactory.getLogger(Websocket.class);

/**

* 连接已建立

* @param session

*/

@OnOpen

public void onOpen(Session session,EndpointConfig config ) {

System.out.println("连接上来了:" + session.getQueryString() + "," + session);

}

/**

* 连接已关闭

*/

@OnClose

public void onClose(Session session, CloseReason reason) {

logger.info( "连接已断开");

}

/**

* 收到消息

* @param message

* @param session

*/

@OnMessage

public void onMessage(String message, Session session) {

if(StringUtils.isBlank(message) || "\"\"".equals(message.trim())){

return ;

}

System.out.println("收到"+ userId +"消息:" + message);

}

/**

* 发生异常

* @param session

* @param error

*/

@OnError

public void onError(Session session, Throwable error) {

error.printStackTrace();

logger.error(session.getId()+"--"+error.getMessage());

}

这是后台的java代码,同样也是四个监听方法。

当我们运行起web项目之后,就已经搭建了一个最简单的WebSocket环境了。

WebSocket主要应用于:网页版的即时通讯(图文语音聊天等),以及网页联机对战游戏。

接下来将用视频展示WebSocet实现的俄罗斯方块联机对战小游戏。

源码地址:

https://github.com/Anyzm/onlineTetris

四、使用websocket应该注意的一些地方

1、websocket长时间不通讯,浏览器出于节省资源的考虑会自动关闭连接。

解决办法:定时发送空消息,服务器过滤空消息。

2、websocket的onclose方法里面,服务器清除一些缓存外,页面还可以做重连操作。但由于断开可能是服务器down掉引起的,所以重连机制可以是重连时间间隔为递增序列。

3、当一些参数或者人为非法操作引起服务器错误时,服务器可自定义关闭状态码,然后页面根据此状态码而不去做重连操作。

4、当电脑黑屏或者处于休眠状态时,页面js会停止运行,这样可能会导致重连时间间隔也会处于一个超长时间状态。所以需要判断时间间隔如果与序列有较大偏差,应该重置时间间隔。

暗中观察

默默关注

那月真美:昨天项目组聚会,打了一系列篮球赛,然后今天全身酸痛,不想动,不想学习,玩游戏也玩累了,于是来发表一篇文章吧

暗中观察

默默关注

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180610G1F8ZQ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券