tomcat8真正支持jsr-356(包含對websocket的支持), tomcat7部分版本的websocket實現不兼容jsr-356。javascript
須要注意websocket與瀏覽器的兼容問題,有些早期版本的瀏覽器支持舊版本的websocket協議,可能會與新版本的websocket不兼容。 博主採用"chrome 版本 33.0.1750.117 m"測試。html
據稱websocket還會有變更,甚至可能從html5中獨立出來,因此不保證當前代碼在將來也能執行。html5
因爲博主所用的eclipse不支持tomcat8,因此採用idea 13 開發(tomcat8.0.3+jdk7+servlet 3.0)。java
Endpoint的session,並非servlet的session,Endpoint的session更象是獨立的記數,Endpoint如何使用servlet的session還在測試。web
參考文檔:
chrome
http://wenku.baidu.com/view/4e3d2d34915f804d2a16c119.html apache
http://tools.ietf.org/html/rfc6455 瀏覽器
http://www.infoq.com/cn/news/2013/07/ee7-websocket-supporttomcat
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="/HelloAction">HelloAction</a> <br> <a href="/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>