使用websocket技术实现消息推送到网页效果。
主要说两种,一种是servlet,一种是struts2. 两种方法后台稍微有点区别,交叉没有试过。
初步测试已调通此两种方法。
第一种:
servlet
import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; import javax.websocket.server.ServerEndpoint; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; public class WebServelt extends WebSocketServlet { private static final long serialVersionUID = -4853540828121130946L; private static ArrayList<MyMessageInbound> mmiList = new ArrayList<MyMessageInbound>(); @Override protected StreamInbound createWebSocketInbound(String str, HttpServletRequest request) { return new MyMessageInbound(); } private class MyMessageInbound extends MessageInbound { WsOutbound myoutbound; @Override public void onOpen(WsOutbound outbound) { try { System.out.println("Open Client."); this.myoutbound = outbound; mmiList.add(this); outbound.writeTextMessage(CharBuffer.wrap("Hello!")); } catch (IOException e) { e.printStackTrace(); } } @Override public void onClose(int status) { System.out.println("Close Client."); mmiList.remove(this); } //当服务器端收到信息的时候,就对所有的连接进行遍历并且把收到的信息发送给所有用户 @Override public void onTextMessage(CharBuffer cb) throws IOException { System.out.println("Accept Message : " + cb); for (MyMessageInbound mmib : mmiList) { CharBuffer buffer = CharBuffer.wrap(cb); mmib.myoutbound.writeTextMessage(buffer); mmib.myoutbound.flush(); } } @Override public void onBinaryMessage(ByteBuffer bb) throws IOException { } } }
页面
<!DOCTYPE html> <html> <head> <meta charset=UTF-8> <title>Tomcat WebSocket Chat</title> <script> //建立客户端websocket var ws = new WebSocket("ws://localhost:8080/Backstage/ws/wsServlet"); //定义ws的一些回调函数 ws.onopen = function() { }; //当有消息传过来时执行的操作 ws.onmessage = function(message) { document.getElementById("chatlog").textContent += message.data + "\n"; }; function postToServer() { ws.send(document.getElementById("msg").value); document.getElementById("msg").value = ""; } function closeConnect() { ws.close(); } </script> </head> <body> <textarea id="chatlog" readonly></textarea> <br /> <input id="msg" type="text" /> <button type="submit" id="sendButton" onClick="postToServer()">Send!</button> <button type="submit" id="sendButton" onClick="closeConnect()">End</button> </body> </html>
<display-name>Websocket</display-name> <servlet> <servlet-name>wsServlet</servlet-name> <servlet-class>com.backstage.calendar.WebServelt</servlet-class> </servlet> <servlet-mapping> <servlet-name>wsServlet</servlet-name> <url-pattern>/ws/wsServlet</url-pattern> </servlet-mapping>
效果:
第二种
@ServerEndpoint("/ws/websocket") public class WebSocketTest { @OnMessage public void onMessage(String message,Session session) throws IOException, InterruptedException { System.out.println("***************"); session.getBasicRemote().sendText(" this is message"); int sentMessage = 0; while(sentMessage < 3){ Thread.sleep(5000); session.getBasicRemote().sendText(" this is one mess " + sentMessage); sentMessage++; } session.getBasicRemote().sendText(" message send over "); } @OnOpen public void onOpen(){ System.out.println(" client connected "); } @OnClose public void onClose(){ System.out.println(" connection closed "); } }
使用@ServerEndpoint("/ws/websocket") 进行访问
html
<!DOCTYPE html> <html> <head> <title>Testing websockets</title> </head> <body> <div> <input type="submit" value="Start" onclick="start()" /> </div> <div id="messages"></div> <script type="text/javascript"> var webSocket; if ('WebSocket' in window) { webSocket = new WebSocket("ws://localhost:8080/Backstage/ws/websocket"); } else if ('MozWebSocket' in window) { webSocket = new MozWebSocket("ws://localhost:8080/websocket"); } else { alert("js"); webSocket = new SockJS("http://localhost:8080/Origami/sockjs/webSocketServer"); } 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 = 'Connection established'; } function onError(event) { //console.log(event); //console.log(event.data); alert(event.data); } function start() { webSocket.send('hello'); return false; } </script> </body> </html>
webSocket = new WebSocket("ws://localhost:8080/Backstage/ws/websocket"); |
报这个错的原因是用了struts2过滤器,web.xml 中配置了 struts2 过滤为 /* ,所以所有的请求都被拦截过去了。
解决办法:
struts.xml 文件中加上
<constant name="struts.action.excludePattern" value="/ws/.*,ws://.*"></constant>
过滤掉ws:// 请求
在此也谢谢参考过的朋友们。上面的例子也是百度出来的资料直接copy过来。由于求解决方案资料搜寻的太多,原链接丢失了。