tomcat8真正支持jsr-356(包含对websocket的支持), tomcat7部分版本的websocket实现不兼容jsr-356。
需要注意websocket与浏览器的兼容问题,有些早期版本的浏览器支持旧版本的websocket协议,可能会与新版本的websocket不兼容。 博主采用"chrome 版本 33.0.1750.117 m"测试。
据称websocket还会有变动,甚至可能从html5中独立出来,所以不保证当前代码在未来也能执行。
由于博主所用的eclipse不支持tomcat8,所以采用idea 13 开发(tomcat8.0.3+jdk7+servlet 3.0)。
Endpoint的session,并不是servlet的session,Endpoint的session更象是独立的记数,Endpoint如何使用servlet的session还在测试。
参考文档:
http://wenku.baidu.com/view/4e3d2d34915f804d2a16c119.html
http://tools.ietf.org/html/rfc6455
http://www.infoq.com/cn/news/2013/07/ee7-websocket-support
package org.sl.action;
//import org.apache.log4j.Logger;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
/**
* Created by shanl on 14-4-14.
*/
@ServerEndpoint(value="/chatendpoint")
public class ChatEndpoint {
//static final Logger logger = Logger.getLogger(ChatEndpoint.class);
static Map<String,Session> sessionMap = new Hashtable<String,Session>();
@OnOpen
public void start(Session session){
System.out.println("Guest"+session.getId()+" join");
sessionMap.put(session.getId(), session);
broadcast("Guest" + session.getId() + " join.");
}
@OnMessage
public void process(Session session, String message){
System.out.println(session.getId()+" say: " + message);
broadcast("Guest"+session.getId()+" [say]: "+message);
}
@OnClose
public void end(Session session){
System.out.println("Guest"+session.getId()+" out.");
sessionMap.remove(session.getId());
broadcast("Guest"+session.getId()+ " out.");
}
@OnError
public void error(Session session, java.lang.Throwable throwable){
System.err.println("Guest" + session.getId() + " error: " + throwable);
end(session);
}
void broadcast(String message){
RemoteEndpoint.Basic remote = null;
Set<Map.Entry<String,Session>> set = sessionMap.entrySet();
for(Map.Entry<String,Session> i: set){
remote = i.getValue().getBasicRemote();
try {
remote.sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package org.sl.action;
import org.omg.CosNaming._NamingContextExtStub;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
/**
* Created by shanl on 14-3-3.
*/
@ServerEndpoint(value="/echoendpoint")
public class EchoEndpoint {
@OnOpen
public void start(Session session){
System.out.println("session "+session.getId()+" open.");
}
@OnMessage
public void process(Session session, String message){
System.out.println("rece:" + message);
RemoteEndpoint.Basic remote = session.getBasicRemote();
int c = Integer.valueOf(message);
for (int i=1; i<=c; i++){
try {
remote.sendText("response "+i);
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@OnClose
public void end(Session session){
System.out.println("session "+session.getId()+" close.");
}
@OnError
public void error(Session session, java.lang.Throwable throwable){
System.err.println("session "+session.getId()+" error:"+throwable);
}
}
package org.sl.action;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by shanl on 14-3-2.
*/
@WebServlet(name="HelloAction" ,urlPatterns={"/HelloAction"},loadOnStartup=1,
initParams={
@WebInitParam(name="name",value="xiazdong"),
@WebInitParam(name="age",value="20")
})
public class HelloAction extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletConfig config = getServletConfig();
HttpSession session = request.getSession();
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<body>");
out.println("Hello world"+"<br />");
out.println("name :"+config.getInitParameter("name")+"<br/>");
out.println("session id :"+session.getId());
out.println("</body>");
out.println("</html>");
out.close();
}
}
package org.sl.action;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Created by shanl on 14-3-2.
*/
//@ServerEndpoint(value = "/Websocket1Action")
public class Websocket1Action extends Endpoint {
private Session session;
//private static final Logger sysLogger = Logger.getLogger("sysLog");
@Override
public void onClose(Session session, CloseReason closeReason) {
System.out.println("onClose");
}
@Override
public void onError(Session session, java.lang.Throwable throwable) {
System.out.println("onError");
}
@Override
public void onOpen(Session session, EndpointConfig config) {
//sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId());
RemoteEndpoint.Basic remote = session.getBasicRemote();
System.out.println("pathParams:"+session.getPathParameters());
System.out.println("requestParams"+session.getRequestParameterMap());
session.addMessageHandler(new MyMessageHandle(remote));
/***
try{
System.out.println("onOpen");
//System.out.println(session.getQueryString());
System.out.println(session.getRequestParameterMap());
session.getBasicRemote().getSendWriter().write("success");
//session.getBasicRemote().sendText("success");
}catch(Exception ex){
ex.printStackTrace();
}
***/
}
private class MyMessageHandle implements MessageHandler.Whole<String> {
RemoteEndpoint.Basic remote = null;
public MyMessageHandle(RemoteEndpoint.Basic remote){
this.remote = remote;
}
@Override
public void onMessage(String s) {
try {
remote.sendText("success");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package org.sl.action;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
* Created by shanl on 14-3-2.
*/
@ServerEndpoint(value = "/Websocket2")
public class Websocket2Action {
private Session session;
//private static final Logger sysLogger = Logger.getLogger("sysLog");
@OnOpen
public void open(Session session,EndpointConfig config) {
this.session = session;
//sysLogger.info("*** WebSocket opened from sessionId " + session.getId());
}
@OnMessage
public void inMessage(Session session,String message) {
//sysLogger.info("*** WebSocket Received from sessionId " + this.session.getId() + ": " + message);
System.out.println("rece:"+message);
try {
session.getBasicRemote().sendText("success");
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void end(Session session) {
//sysLogger.info("*** WebSocket closed from sessionId " + this.session.getId());
}
}
<!DOCTYPE html>
<html>
<head>
<title>echoendpoint.html</title>
<script language="JavaScript">
var wsuri = "ws://localhost:8080/echoendpoint";
var ws = null;
function connectEndpoint(){
ws = new WebSocket(wsuri);
ws.onmessage = function(evt) {
//alert(evt.data);
document.getElementById("echo").value = evt.data;
};
ws.onclose = function(evt) {
//alert("close");
document.getElementById("echo").value = "end";
};
ws.onopen = function(evt) {
//alert("open");
document.getElementById("echo").value = "open";
};
}
function sendmsg(){
ws.send(document.getElementById("send").value);
}
</script>
</head>
<body onload="connectEndpoint()">
<input type="text" size="20" value="5" id="send"> <input type="button" value="send" onclick="sendmsg()"> <br>
<input type="text" id="echo">
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>websocket1.html</title>
<script type="text/javascript">
var wsuri = "ws://localhost:8080/Websocket1Action";
var ws = null;
function startWebSocket() {
if ('WebSocket' in window)
ws = new WebSocket(wsuri);
else if ('MozWebSocket' in window)
ws = new MozWebSocket(wsuri);
else
alert("not support");
ws.onmessage = function(evt) {
alert(evt.data);
};
ws.onclose = function(evt) {
alert("close");
};
ws.onopen = function(evt) {
alert("open");
};
}
function sendMsg() {
ws.send(document.getElementById('writeMsg').value);
}
</script>
</head>
<body onload="startWebSocket();">
<input type="text" id="writeMsg"/>
<input type="button" value="send" onclick="sendMsg()"/>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>websocket2.html</title>
<script type="text/javascript">
var wsuri = "ws://localhost:8080/Websocket2/";
var ws = null;
function startWebSocket() {
if ('WebSocket' in window)
ws = new WebSocket(wsuri);
else if ('MozWebSocket' in window)
ws = new MozWebSocket(wsuri);
else
alert("not support");
ws.onmessage = function(evt) {
alert(evt.data);
};
ws.onclose = function(evt) {
alert("close");
};
ws.onopen = function(evt) {
alert("open");
};
}
function sendMsg() {
ws.send(document.getElementById('writeMsg').value);
}
</script>
</head>
<body onload="startWebSocket();">
<input type="text" id="writeMsg"/>
<input type="button" value="send" onclick="sendMsg()"/>
</body>
</html>
<%-- Created by IntelliJ IDEA. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index.jsp</title>
</head>
<body>
index.jsp<br/>
<a href="https://my.oschina.net/HelloAction">HelloAction</a> <br>
<a href="https://my.oschina.net/WebsocketAction">WebsocketAction</a> <br>
<a href="websocket1.html">websocket1.html</a> <br>
<a href="websocket2.html">websocket2.html</a> <br>
<a href="echoendpoint.html">echoendpoint.html</a> <br>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>chatendpoint.html</title>
<script language="JavaScript">
var wsuri = "ws://localhost:8080/chatendpoint";
var ws = null;
function connectEndpoint(){
window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket){
alert("WebSocket not supported by this browser");
return;
}
ws = new WebSocket(wsuri);
ws.onmessage = function(evt) {
//alert(evt.data);
var old = document.getElementById("echo").value;
document.getElementById("echo").value = old+evt.data+"\r\n";
};
ws.onclose = function(evt) {
//alert("close");
document.getElementById("echo").value = "server disconnect.\r\n";
};
ws.onopen = function(evt) {
//alert("open");
document.getElementById("echo").value = "connect server.\r\n";
};
}
function sendmsg(){
ws.send(document.getElementById("send").value);
}
</script>
</head>
<body onload="connectEndpoint()">
<input type="text" size="20" value="hi~" id="send"> <input type="button" value="send" onclick="sendmsg()"> <br>
<textarea id="echo" rows="50" cols="50">
</textarea>
</body>
</html>