WebSocket搭建教程
程序员文章站
2022-06-22 14:54:19
如何搭建一个websocket呢?
第一步,编写一个简单的jsp文件,它主要有websocket连接和4个websocket响应事件。
<%@ page langua...
如何搭建一个websocket呢?
第一步,编写一个简单的jsp文件,它主要有websocket连接和4个websocket响应事件。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%-- <jsp:include page="/js/jspfunc/supplierBackGroundMan/supplierBackGroundMan.jsp" /> --%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; %> <!DOCTYPE html> <html> <head> <title>Testing websockets</title> <script type="text/javascript" src="<%=path %>/js/jquery-1.11.3.js"></script> <script type="text/javascript" src="<%=path %>/js/zzcjs/jquery.serializejson.min.js"></script> <script type="text/javascript"> var webSocket = new WebSocket('ws://192.168.3.130:8080/supplier/websocket/chat'); webSocket.onerror = function(event) { alert(event.data); }; webSocket.onclose = function(event) { document.getElementById('messages').innerHTML = 'onclose'; }; webSocket.onopen = function(event) { document.getElementById('messages').innerHTML = 'open'; }; webSocket.onmessage = function(event) { document.getElementById('messages').innerHTML += '<br/>' + event.data; }; function start() { webSocket.send(JSON.stringify({type:1,message:'huang1',userid:'1',farmid:'1'})); return false; } </script> </head> <body> <p> <input type="submit" value="Start" onclick="start()" /> </p> <p id="messages"></p> </body> </html>
第二步,配置struts.xml配置文件
<!--不拦截ws请求 --> <constant name="struts.action.excludePattern" value="/websocket/chat"></constant>
第三步,编写后台代码
//onOpen 我们创建一个连接到服务器的连接时将会调用此方法。 //onClose 我们关闭一个连接到服务器的连接时将会调用此方法。 //onError 当客户端-服务器通信发生错误时将会调用此方法。 //onMessage事件提供了一个data属性,它可以包含消息的Body部分。消息的Body部分必须是一个字符串,可以进行序列化/反序列化操作,以便传递更多的数据。 package com.nmfz.app.websocket; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.websocket.EndpointConfig; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.directwebremoting.json.JsonUtil; import org.directwebremoting.json.parse.JsonParseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.web.context.ContextLoader; import org.springframework.web.context.support.WebApplicationContextUtils; import com.alibaba.fastjson.JSON; import com.nmfz.app.action.SharedFarmUsers; import com.nmfz.app.manager.SharedFarmUsersManager; import com.nmfz.app.manager.impl.SharedFarmUsersManagerImpl; import net.sf.json.JSONObject; /** * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。 * configurator:通过GetHttpSessionConfigurator可以在onOpen方法中取得HttpSession,然后通过HttpSession的ServletContext容器可以取得spring的service,实现在websocket中变相注入spring bean。 * @author zho */ @ServerEndpoint(value = "/websocket/chat",configurator=GetHttpSessionConfigurator.class) public class MyWebSocket{ //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 private final static AtomicInteger onlineCount = new AtomicInteger(0); //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识 // private static CopyOnWriteArraySetwebSocketSet = new CopyOnWriteArraySet (); private static List clients = new ArrayList<>(); //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; private HttpSession httpSession; // ngs static int userid ; @OnOpen public void onOpen(Session session, EndpointConfig config) throws IOException, InterruptedException { this.session = session; this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); clients.add(this); //当前客户端加入集合 MyWebSocket.onlineCount.incrementAndGet();//在线数加1 sendMessage("打开");//向此用户发送一条最新的偷菜记录 } @OnClose public void onClose() throws IOException, InterruptedException { clients.remove(this); //从set中删除 MyWebSocket.onlineCount.decrementAndGet();//在线数减1 System.out.println("close"); } @OnMessage public void onMessage(String message, EndpointConfig config) throws IOException, InterruptedException { sendMessage(message); } @OnError public void onError(Throwable t) throws Throwable { t.printStackTrace(); System.out.println("error"); } /** * 发送消息给客户端 * @param message * @throws IOException */ public void sendMessage(String message) throws IOException{ //自己和自己对话 try { // this.session.getBasicRemote().sendText(message);//同步 this.session.getAsyncRemote().sendText(message);//异步 } catch (Exception e) { e.printStackTrace(); } // MyWebSocket.broadcast(message); } /** * 给某个用户发送消息 * * @param userName * @param message */ /* public void sendMessageToUser(String userName, TextMessage message) { for (MyWebSocket client : clients) { if (client.getAttributes().get("websocket_username").equals(userName)) { try { if (client.isOpen()) { client.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } break; } } } */ /*广播:遍历客户端集,发送消息,注意发送要用的session,用session.getBasicRemote().sendText(msg)发送消息*/ public static void broadcast(String msg) { for (MyWebSocket client : clients) {//遍历所有 try {//如果这个client已经在线 synchronized (client) { client.session.getBasicRemote().sendText(msg);//发送消息 } } catch (IOException e) {//如果这个client不在线 // log.debug("Chat Error: 向用户"+client.getUser().getUsername()+"发送消息失败", e); clients.remove(client); try { client.session.close(); } catch (IOException e1) { // Ignore } // String message = String.format("-- %s %s", client.user.getUsername(), "已经下线."); // broadcast(message); } } } /** * @触发事件 * @param msg * @param pa1 */ public void triggerEvent(String msg) { try { onMessage(msg,null); } catch (Exception e) { e.printStackTrace(); } } /** * 获取当前在线人数 * @return */ public static int currentOnline() { return onlineCount.get(); }
第四步,编写一个继承Configurator的子类GetHttpSessionConfigurator,通过GetHttpSessionConfigurator可以在onOpen方法中取得HttpSession,然后通过HttpSession的ServletContext容器可以取得spring的service,实现在websocket中变相注入spring bean。
package com.nmfz.app.websocket; 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; public class GetHttpSessionConfigurator extends Configurator{ @Override public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); if(httpSession != null){ config.getUserProperties().put(HttpSession.class.getName(), httpSession); } } }
推荐阅读
-
html5 Canvas画图教程(9)—canvas中画出矩形和圆形
-
html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法
-
html5 Canvas画图教程(5)—canvas里画曲线之arc方法
-
html5 Canvas画图教程(8)—canvas里画曲线之bezierCurveTo方法
-
iOS开发教程之识别图片中二维码功能的实现
-
html5 Canvas画图教程(7)—canvas里画曲线之quadraticCurveTo方法
-
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
-
html5 Canvas画图教程(11)—使用lineTo/arc/bezierCurveTo画椭圆形
-
html5 Canvas画图教程(10)—把面拆成线条模拟出圆角矩形
-
腾讯小王卡怎么免费升级为大王卡 腾讯小王卡升级大王卡方法教程。