微信小程序websocket java服务器怎么搭建?
微信小程序websocket java服务器怎么搭建,必须通过wss访问 用的tomcat服务器
<p>我这里有四个类都是关于Java搭建websocket 的服务器搭建,运行在tomcat上面,首先你要搞明白的是不管是微信小程序还是什么H5前端我们后端的服务搭建关系并不大。需要实现的wss访问其实和前端也没有关系。主要是我们的nginx版本在1.8以上就支持wss访问。wss其实也就是我们平时的纯属协议加密的使用443端口。
</p>
<p>package com.manager.base.services.websocket; import javax.websocket.HandshakeResponse; import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpointConfig; /** */ public class WebSocketConfigurator extends ServerEndpointConfig.Configurator { @Override public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { request.getHttpSession(); } /* @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession=(HttpSession) request.getHttpSession(); sec.getUserProperties().put(HttpSession.class.getName(),httpSession); }*/
}
</p>
<p>
package com.manager.base.services.websocket; import javax.websocket.Session; /** * Created by Administrator on 2018/9/28. */ public class WebSocketDto { private String code; //客户端传入的唯一标识 private String fileName; //文件名称 private int totalNum; //总数量 private int handleNum = 0; //当前操作数量 private Session session; //当前websocket的session public String getCode() { return code; } public void setCode(String code) { this.code = code; } public int getTotalNum() { return totalNum; } public void setTotalNum(int totalNum) { this.totalNum = totalNum; } public int getHandleNum() { return handleNum; } public void setHandleNum(int handleNum) { this.handleNum = handleNum; } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } }
</p>
<p>package com.manager.base.services.websocket; import com.alibaba.fastjson.JSON; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.collect.Maps; import org.apache.tomcat.websocket.WsSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.websocket.Session; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit;
/** * @author zhouqun */ public class WebSocketManger { private static Logger logger = LoggerFactory.getLogger(WebSocketManger.class); /** * 写入或者访问30分钟之后清除, 客户端可在此时间区间内续命 */ // guava cache 包冲突了, 不知道是哪个包 // private static Cache cache = CacheBuilder.newBuilder() // .expireAfterAccess(30, TimeUnit.MINUTES) // .expireAfterWrite(30, TimeUnit.MINUTES) // .build(new CacheLoader() { // @Override // public WsSession load(Integer integer) throws Exception { // return null; // } // }); private static Map cache = new ConcurrentHashMap<>(); public static void recodeSession(String userId, WsSession session) { cache.put(userId, session); } public static Session getSession(String userId) { // return cache.getIfPresent(userId); return cache.get(userId); } public static void removeSession(String userId) { // cache.invalidate(userId); cache.remove(userId); } public static long getOnlineUserCount() { return cache.size(); } /** * 批量发送消息 * * @param message 消息体 */ public static void sendMessage(Map message) { if (null != message) { for (Map.Entry entry : message.entrySet()) { String userId = entry.getKey(); Object value = entry.getValue(); // WsSession session = cache.getIfPresent(userId); WsSession session = cache.get(userId); if (null == session || !session.isOpen()) { logger.error("WebSocket发送信息失败: [未找到session或者session已关闭, userId={}]", entry.getKey()); continue; } try { if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Float || value instanceof Double || value instanceof Long || value instanceof String){ session.getBasicRemote().sendText(value.toString()); }else{ session.getBasicRemote().sendText(JSON.toJSONString(value)); } } catch (IOException e) { logger.error("WebSocket发送信息失败: [userId={}]", entry.getKey(), e); } } } } }
</p>
<p>package com.manager.base.services.websocket; import com.google.common.collect.Maps; import com.manager.base.entitys.UserInformationBean; import com.manager.base.interceptor.AuthorityInterceptor; import com.manager.base.listener.SimpleSessionListener; import com.manager.base.utils.Public; import org.apache.commons.lang.StringUtils; import org.apache.tomcat.websocket.WsSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpSession; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;
/** * web socket服务端, 实例由web容器创建而不是spring * * @author zhouqun */ @ServerEndpoint(value = "/webSocket", configurator = WebSocketConfigurator.class) public class WebSocketRegister { private Logger logger = LoggerFactory.getLogger(this.getClass()); //用于记录接入的websocket连接 private static ConcurrentHashMap websocketMap = new ConcurrentHashMap<>(); @OnOpen public void onOpen(Session session, EndpointConfig config) { logger.info(" websocket open , httpSessionId = {} " , ((WsSession) session).getHttpSessionId() ); try { System.out.println("连接加入成功。。。。。。。。。。。。。。"); String systemCode = session.getRequestParameterMap().get("systemCode").get(0).toString(); String app = Public.mapTo(session.getRequestParameterMap().get("app").get(0).toString(),""); Session s = WebSocketManger.getSession(Public.mapTo(systemCode,"")); WebSocketDto webSocketDto = new WebSocketDto(); webSocketDto.setCode(systemCode); webSocketDto.setSession(session); if (s == null ) { WsSession wsSession = (WsSession) session; WebSocketManger.recodeSession(systemCode, wsSession); } else { Map map = Maps.newHashMap(); //当前session已经登录成功了,关掉老的session if (Public.mapTo(app,-1)==1){ //app登陆 map.put(systemCode, "logout"); WebSocketManger.sendMessage(map); WebSocketManger.recodeSession(systemCode, (WsSession) session); }else if ( getUser(session) != null ) { String currentHttpSessionId = ((WsSession) session).getHttpSessionId(); String lastHttpSessionId = ((WsSession) s).getHttpSessionId(); if( !currentHttpSessionId.equals( lastHttpSessionId )){ map.put(systemCode, "logout"); WebSocketManger.sendMessage(map); WebSocketManger.recodeSession(systemCode, (WsSession) session); HttpSession httpSession = SimpleSessionListener.getSession(((WsSession) s).getHttpSessionId()); httpSession.invalidate(); }else{ WsSession wsSession = (WsSession) session; WebSocketManger.recodeSession(systemCode, wsSession); } } } }catch (Exception e ){ logger.error("WebSocket onOpen:", e); } } @OnClose public void onClose(Session session) throws Exception{ System.out.println("连接关闭。。。。。。。。。。。。。。" ); try { String systemCode = session.getRequestParameterMap().get("systemCode").get(0).toString(); if (StringUtils.isNotEmpty(systemCode)){ WsSession wsSession = (WsSession) session; String sessionId = wsSession.getId(); WsSession existedWsSession = (WsSession) WebSocketManger.getSession(systemCode); String existedSessionId = existedWsSession.getId(); if (sessionId.equals(existedSessionId)) { logger.info("删除上一个账号的session"); WebSocketManger.removeSession(Public.mapTo(systemCode,"")); } } }catch (Exception e) { logger.info("删除失败" ,e ); } } @OnMessage public void onMessage(String message, Session session) throws IOException { // do noting // just test // String[] data = message.split(":"); // String command = data[0]; // String systemCode = data[1]; // if ("connect".equals(command)) { // Session s = WebSocketManger.getSession(Integer.valueOf(systemCode)); // if (s == null) { // WsSession wsSession = (WsSession) session; // WebSocketManger.recodeSession(Integer.valueOf(systemCode), wsSession); // } else { // Map map = Maps.newHashMap(); // map.put(Integer.valueOf(systemCode), "logout"); // WebSocketManger.sendMessage(map); // } // } else { // // TODO // } // Map map = Maps.newHashMap(); // map.put(0, message); // WebSocketManger.sendMessage(map); } @OnError public void onError(Session session, Throwable error){ logger.error("WebSocket onError", error ); logger.error("WebSocket异常:{}", error.getLocalizedMessage(), error.getCause()); } private UserInformationBean getUser(Session session){ try { WsSession wsSession = (WsSession) session; HttpSession httpSession = SimpleSessionListener.getSession(wsSession.getHttpSessionId()); if (null != httpSession && null != httpSession.getAttribute(AuthorityInterceptor.USER_BEAN) && httpSession.getAttribute(AuthorityInterceptor.USER_BEAN) instanceof UserInformationBean) { return (UserInformationBean) httpSession.getAttribute(AuthorityInterceptor.USER_BEAN); } }catch (Exception e){ logger.error("WebSocket接口获取用户信息异常", e ); } return null; } public static ConcurrentHashMap getWebsocketMap() { return websocketMap; } public static void setWebsocketMap(ConcurrentHashMap websocketMap) { WebSocketRegister.websocketMap = websocketMap; } }
</p>
<p>前端的实现就比较简单只要连接后端的服务就好 try{ if (socket) { socket.close(); } // var socket = new WebSocket("wss://*****/ksglxt/webSocket?systemCode=" + JSON.parse(localStorage.getItem('content')).admin.systemcode +"&app=0"); var socket = new WebSocket("ws://192.168.1.5:8080/ks_manager/webSocket?systemCode=" + JSON.parse(localStorage.getItem('content')).admin.systemcode); socket.onopen = function (e) { console.log('链接!'); } socket.onmessage = function (e) { console.log(e.data); if (e.data === 'logout') { socket.close(); $(".logOut_winBox").show(); //alert("你的账号已在别处登录!") //localStorage.clear(); //location.href = 'login/login.html'; } } $('#sureLogOut').on("click", function () { location.href = 'login/login.html'; }) }catch (e){ throw e; } 至于什么时候实现wss主要是看你是否使用传输加密协议如果使用了传输加密协议那就直接在nginx配置域名的时候加上websoket的配置以下是我的配置可以参考 location /ksglxt/webSocket { proxy_pass http://127.0.0.1:8081; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Scheme $scheme; } </p>
<p>以上仅供参考如有不明白之处可以联系</p>
- 等 最代码怎么获取牛币啊?
- 完 谁来告诉我最代码上线的时间,答对者给5牛币,先来先得
- 等 牛友们,大家好,你们做程序员多久了?现在还好吗?
- 完 在微信打开的页面里进行app下载
- 等 最代码2014年欢乐聚声会
- 完 mysql如何查询表数据并且对3个字段降序的SQL?
- 完 最代码牛币机制改革
- 完 成功的在bae上使用了自定义运行环境 jetty+nginx的组合,大家对jetty+nginx优化有哪些心得?
- 完 进来分享一下各位牛牛是如何加入最代码大家庭的?
- 等 为什么java BufferedImage类处理大图直接抛出内存溢出的异常?
- 等 最代码是否开发手机app客户端?
- 完 java程序员学习哪些java的技术?java有哪些框架?都能做哪方面的开发?
- 等 php格式网页文件怎么运行?
- 等 Java volatile值获取的问题
- 等 前端vue,拦截了登录后台后,返回的token,requests拦截token,但是发送请求的时候,就出现跨越异常
- 等 大专本科计算机科班怎么找到Java工作?
- 等 eclipse怎么把三个java swing游戏项目合成一个项目?
- 完 伙伴们,大家都有什么好的解压方式么,分享一下~
- 完 三四线城市,6、7k,运维工作,索然无味,想去辞职上培训,各位牛牛有什么建议嘛
- 等 jsp页面输入中文变成问号
- 等 JPA在线上运行一段时间后报错Caused by: java.lang.IncompatibleClassChangeError: null
- 等 PHP 这个规则用preg_match_all怎么写
- 等 大佬们,有没有知道Alfresco如何配置LDAP登录呢?
- 等 php的install目录是框架带的吗?