websocket即时通信

websocket 通信

一.先说说WEB即时通信技术

一般通过两种方式来实现Web实时用:
1.轮询机制
(轮询):这是最早的一种实现实时 Web 应用的方案。客户端以一定的时间间隔向服务端发出请求,以频繁请求的方式来保持客户端和服务器端的同步。这种同步方案的缺点是,当客户端以固定频率向服务 器发起请求的时候,服务器端的数据可能并没有更新,这样会带来很多无谓的网络传输,所以这是一种非常低效的实时方案

(Comet的长轮询):是对定时轮询的改进和提高,目地是为了降低无效的网络传输。当服务器端没有数据更新的时候,连接会保持一段时间周期直到数据或状态改变或者 时间过期,通过这种机制来减少无效的客户端和服务器间的交互。当然,如果服务端的数据变更非常频繁的话,这种机制和定时轮询比较起来没有本质上的性能的提 高

2.流技术
    常就是在客户端的页面使用一个隐藏的窗口向服务端发出一个长连接的请求。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务 器端的连接不过期。通过这种机制可以将服务器端的信息源源不断地推向客户端。这种机制在用户体验上有一点问题,需要针对不同的浏览器设计不同的方案来改进 用户体验,同时这种机制在并发比较大的情况下,对服务器端的资源是一个极大的考验。

    WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

二.搭建过程:

需要下载:websocket-api.jar包,这里需要注意了,在高版本的Tomcat中,已经自带这个jar包了(Tomcat7.0.70以上都有)。

1.新建一个WebSocketTest的类通过@ServerEndpoint(value="/websocketTest")
该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。

2.通过在某个方法上加上@OnOpen注解,表明连接建立成功调用该方法
可选参数:(javax.websocket.Session session)
session为与某个客户端的连接会话,需要通过它来给客户端发送数据

3.在某个方法上加上@OnMessage注解,表明收到客户端消息后调用该方法
参数为:(String message, javax.websocket.Session session)
message为客户端发送过来的消息,session为可选的参数

4.在某个方法上加上@onClose()注解,表明连接关闭调用该方法

5.在某个方法上加上@OnError注解,表明发生错误时调用该方法
参数为(Session session,Throwable error)

这样大致的服务端就完成了

页面上连接服务器是通过js来操作的:
var webSocket = new WebSocket('ws://<%=websocketurl%>/websocketTest');
webSocket.onerror = function(event) {
onError(event)
};

webSocket.onopen = function(event) {
onOpen(event)
};

webSocket.onmessage = function(event) {
onMessage(event)
};

function onMessage(event) {
document.getElementById('messages').innerHTML += '<br />'+ event.data;
}

function onOpen(event) {
document.getElementById('messages').innerHTML = 'webSocket 连接建立成功!';
}

function onError(event) {
alert(event.data);
}

function sendMsg(){
for(var i=0;i<1;i++){
webSocket.send(document.getElementById('sendPeople').value+"*"+document.getElementById('sendContent').value);
}
document.getElementById('sendContent').value="";
return false;
}

这样就实现了websocket的通信了,可以主动向浏览器进行推送消息,由于websocket是基于HTHL5开发的,所以低版本的IE就不支持了。

最后提一下,websocket中有自己的session,这与HttpSession是不一样的,那么我们应该怎样通过websocket的session来获取HttpSession呢?这里源码中也写好了,网上教程也很多,就说一下最普遍的方法:

1.建一个GetHttpSessionConfigurator类并继承Configurator类
代码如下:

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import javax.websocket.server.ServerEndpointConfig.Configurator;
/*
 * 获取HttpSession
 * 
 */
public class GetHttpSessionConfigurator extends Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        HttpSession httpSession=(HttpSession) request.getHttpSession();
        sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }
}


2.在@ServerEndpoint 注解里面添加 configurator 属性
如:@ServerEndpoint(value="/websocketTest",configurator=GetHttpSessionConfigurator.class)

3.在onOpen方法里加入参数EndpointConfig config即可获取HttpSession
如:HttpSession httpsession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());

以上三步即可解决session转化的问题!



三.效果图


1.指向性单对单聊天效果图:



2.三人聊天效果图:



四.遇到的错误

在这里也遇到了一个错误,可能也是比较常见的,给大家说一下:
开始时我用Myeclipse新建了一个项目(jdk1.7,tomcat6.0的libraries运行环境),在运行时我用了tomcat7.0,于是浏览器会提示failed: Error during WebSocket handshake: Unexpected response code: 404,很纳闷,找不到地址,怎么可能呢?,搜了一些帖子隐约得的发现一些问题,我更换了运行环境,将tomcat6.0的libraries更换为tomcat8.0的,没有手动加入websocket-api.jar包,项目没有报错,于是看了看发现tomcat8.0的libraries含有websocket-api.jar包,并且用tomcat8.0进行运行,完全正常了,后来分析了一下发现这种错误就是jar包冲突导致的。



这里附上源码链接:http://download.csdn.net/detail/qq_27063119/9747437


网上的这位仁兄写的比较好,简单易懂,推荐看看   http://blog.chenzuhuang.com/archive/28.html

发布了48 篇原创文章 · 获赞 74 · 访问量 22万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章