赞
踩
前端建立websocket链接的时候,控制台打印Error during WebSocket handshake: Unexpected response code: 200,
这种情况多半是因为服务端的拦截器出了问题。
要知道websocket是基于http的,建立websocket链接的时候也用经过握手,这个握手走的就是传统的http请求(好像不同浏览器实现的细节也不太一样,chrome应该是走的http),因此如果服务端有拦截器的话,是会把握手信息拦截下来的。
解决办法:
我的服务端是springboot+shrio, 解决办法很简单
@Configuration public class ShiroConfig { /** * Shiro的Web过滤器Factory 命名:shiroFilter<br /> * * @param securityManager * @return */ @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { System.out.println(("注入Shiro的Web过滤器-->shiroFilter" + ShiroFilterFactoryBean.class)); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); shiroFilterFactoryBean.setLoginUrl("/user/login"); shiroFilterFactoryBean.setSuccessUrl("/index"); shiroFilterFactoryBean.setUnauthorizedUrl("/403"); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/user/login", "anon"); filterChainDefinitionMap.put("/websocket", "anon"); //避免拦截/websocket链接 filterChainDefinitionMap.put("/reg", "anon"); filterChainDefinitionMap.put("/plugins/**", "anon"); filterChainDefinitionMap.put("/pages/**", "anon"); filterChainDefinitionMap.put("/api/**", "anon"); filterChainDefinitionMap.put("/dists/img/*", "anon"); filterChainDefinitionMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.getFilters().put("authc", new MyFormAuthenticationFilter()); return shiroFilterFactoryBean; } }
核心代码其实就这一行 filterChainDefinitionMap.put("/websocket", “anon”);
另外附上我的websocket配置:
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
/** * 坑点: * \@ServerEndpoint注解的类,不可以用AOP, 否则会出现无法注入的情况 */ @ServerEndpoint(value = "/websocket") @Component public class WSServer { private static Hashtable<String, WSServer> websocketTable = new Hashtable<>(); private static final String TYPE_INIT = "0"; private static final String TYPE_EXCEPTION = "-1"; private Session session; //心跳定时器 private Timer pulsTimer; private long timerPeriod = 45 * 1000; private String userName; //标识用户 @OnOpen public void onOpen(Session session){ this.session = session; //第一个链接后,启动定时器发送定时心跳 if(pulsTimer == null){ pulsTimer = new Timer(); pulsTimer.schedule(new TimerTask() { @Override public void run() { try { WSServer.broadcast(WSMessage.pulseMessage()); }catch (IOException e){ e.printStackTrace(); } } }, 0L, timerPeriod); } } @OnClose public void onClose() { if(!StringUtils.isEmpty(userName)){ websocketTable.remove(userName); } } /** * { * type:"1", * message:"JSON", * rdnum:"用来唯一标识这条消息的id" * } */ @OnMessage public void onMessage(String message, Session session) { try { JSONObject jsonObject = JSONObject.parseObject(message); String type = jsonObject.getString("type"); switch (type){ case TYPE_INIT: init(jsonObject);break; default:; } }catch (JSONException e){ e.printStackTrace(); WSMessage wsMessage = new WSMessage(TYPE_EXCEPTION, "json格式出错"); sendMessage(wsMessage); } } @OnError public void onError(Session session, Throwable error) { error.printStackTrace(); } public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } public void sendMessage(WSMessage message){ try { sendMessage(message.toString()); }catch (IOException e){ e.printStackTrace(); } } public void init(JSONObject jsonObject){ JSONObject messge = jsonObject.getJSONObject("message"); if(messge != null){ String userName = messge.getString("userName"); if(StringUtils.isEmpty(userName)){ websocketTable.put(userName, this); } } } public static synchronized void broadcast(String message) throws IOException{ for(Iterator<String> iterator = websocketTable.keySet().iterator(); iterator.hasNext(); ){ WSServer wsServer = websocketTable.get(iterator.next()); wsServer.sendMessage(message); } } public static synchronized void broadcast(WSMessage message) throws IOException{ broadcast(message.toString()); } public static synchronized void broadcast(WSMessage message, String userName) throws IOException{ broadcast(message.toString(), userName); } public static synchronized void broadcast(String message, String userName) throws IOException{ WSServer wsServer = websocketTable.get(userName); if(wsServer != null){ wsServer.sendMessage(message); } public static synchronized int getOnlineCount() { return websocketTable.size(); } }
看都看到这儿了,点个赞再走呗(。・∀・)ノ
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。