Java使用WebSocket

随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。

在WebSocket规范提出之前,开发人员若要实现这些实时性较强的功能,经常会使用折衷的解决方法:轮询(polling)和Comet技术。其实后者本质上也是一种轮询,只不过有所改进。伴随着HTML5推出的WebSocket,真正实现了Web的实时通信,使B/S模式具备了C/S模式的实时通信能力。WebSocket的工作流程是这样的:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过TCP连接传输数据。

环境

Tomcat 7.0.47以上
Java jdk7以上,jdk6不支持WebSocket
在MyEclipse中引入tomcat/lib下面的websocket-api.jar

后台程序

@ServerEndpoint(value = "/websocket/{user}")
public class MyServerEndpoint {
    private Session session;

    @OnOpen
    public void onOpen(Session session,@PathParam(value="user") String user) {
        this.session = session;
        System.out.println(user + "打开:" + session.getId());
    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println("处理消息:" + this.session.getId());
        this.session.getBasicRemote().sendText(message);
    }

    @OnClose
    public void onClose() {
        System.out.println("关闭:" + this.session.getId());
    }
}

前台页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()    + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>WebSocket页面</title>
<script type="text/javascript">
    var ws;
    var url = "ws://localhost/websocket/websocket/xiaoyu";
    var result;
    function initWebSocket() {
        result = document.getElementById("result");
        if ("WebSocket" in window) {
            ws = new WebSocket(url);
        } else if ("MozWebSocket" in window) {
            ws = new MozWebSocket(url);
        } else {
            result.innerHTML = "浏览器不支持WebSocket<br>";
        }
        ws.onopen = function() {
            result.innerHTML = "开启:" + "<br>";
            ws.send("index");
        };
        ws.onmessage = function(event) {
            result.innerHTML += "接受消息: " + event.data + "<br>";
        };
        ws.onclose = function(event) {
            result.innerHTML += "关闭" + "<br>";
        };
    }
    function send() {
        ws.send(document.getElementById("msg").value);
    }
</script>
</head>
<body onload="initWebSocket();">
    <h1>WebSocket示例</h1>
    <hr>
    <div id="result"></div>
    <textarea rows="5" cols="20" id="msg"></textarea>
    <br>
    <button onclick="send()">发送</button>
</body>
</html>

显示效果

配置运行tomcat就会出现如上的显示界面,表示WebSocket配置成功了,恭喜!

错误集锦

MyEclipse启动后,index页面出现“关闭”字样

如果在Tomcat启动后,访问index.jsp依然没能成功:修改tomcat安装文件夹下面conf/context.xml文件,在WatchedResource下面添加即可,表示加载前先问上级loader,同java一般模式;false,先从本loader开始尝试加载,但是Eclipse一般不会出现这样的问题!

<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Loader delegate="true" />

参考

Java后端WebSocket的Tomcat实现
Tomcat7 配置 WebSocket