• webSocket通信


    配置路径,在项目加载的时候就开始运行:

    import javax.annotation.Resource;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.config.annotation.EnableWebSocket;
    import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
    import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
    
    import com.hncy.optima.websocket.handler.MessageHandshakeInterceptor;
    import com.hncy.optima.websocket.handler.MessageWebSocketHandler;
    
    @Configuration
    @EnableWebMvc
    @EnableWebSocket
    public class WebConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
    
    @Resource
    private MessageWebSocketHandler messageWebSocketHandler;
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(messageWebSocketHandler,"/message.msg").addInterceptors(new MessageHandshakeInterceptor());
    registry.addHandler(messageWebSocketHandler,"/sockjs/message.msg").addInterceptors(new MessageHandshakeInterceptor())
    .withSockJS();
    }
    
    @Bean
    public WebSocketHandler messageWebSocketHandler(){
    return new MessageWebSocketHandler();
    }
    
    }

    ***************************************************从前台开始************************************

    //------------------------------------------websocket---------------------------------------------

    var websocket;
    
    if ('WebSocket' in window) {
    //websocket = new WebSocket("ws://${socketPath}/message.msg");
    websocket = new WebSocket("ws://127.0.0.1:6060/message.msg");
    } else if ('MozWebSocket' in window) {
    //websocket = new MozWebSocket("ws://${socketPath}/message.msg");
    websocket = new MozWebSocket("ws://127.0.0.1:6060/message.msg");
    } else {
    //websocket = new SockJS("ws://${socketPath}/sockjs/message.msg");
    websocket = new SockJS("ws://127.0.0.1:6060/sockjs/message.msg");
    }
    
    websocket.onopen = function (evnt) {
    alert("onopen");
    };
    
    websocket.onmessage = function (evnt) {
    alert(evnt.data);
    };
    
    websocket.onerror = function (evnt) {
    //alert("onerror:"+evnt);
    //for(var name in evnt){
    //    alert(name + " : " +evnt[name]);
    //}
    };
    
    websocket.onclose = function (evnt) {
    
    };

    jSP页面

    建立连接时websocket.onopen响应,当后台向前台发送信息时,websocket.onmessage接受信息,evnt只能是String类型,但是我们可以用JSON来传递多个参数。

    ********************************************************获取用户**************************

    package com.hncy.optima.websocket.handler;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpSession;
    
    import org.springframework.http.server.ServerHttpRequest;
    import org.springframework.http.server.ServerHttpResponse;
    import org.springframework.http.server.ServletServerHttpRequest;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.server.HandshakeInterceptor;
    
    import com.optima.bedrock.utils.LoginInstance;
    import com.optima.bedrock.utils.Tools;
    
    
    public class MessageHandshakeInterceptor implements HandshakeInterceptor{
    
    @Override
    public boolean beforeHandshake(ServerHttpRequest request,
    ServerHttpResponse response, WebSocketHandler wsHandler,
    Map<String, Object> attributes) throws Exception {
    String loginName = LoginInstance.getUser().getLoginName();
    if(Tools.transNull(loginName).equals("") == false){
    attributes.put("loginName", loginName);
    }else{
    return false;
    }
    
    //在这里如果不需要定向发送,可以设置loginName为一个定值,返回true
    return true;
    }
    
    /* (non-Javadoc)
    * @see org.springframework.web.socket.server.HandshakeInterceptor#afterHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.lang.Exception)
    */
    @Override
    public void afterHandshake(ServerHttpRequest request,
    ServerHttpResponse response, WebSocketHandler wsHandler,
    Exception exception) {
    // TODO Auto-generated method stub
    
    }
    
    }

    获取用户信息为后面发送消息通信做准备

    ******************************响应,发送消息的方法*****************************

    package com.hncy.optima.websocket.handler;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.socket.CloseStatus;
    import org.springframework.web.socket.TextMessage;
    import org.springframework.web.socket.WebSocketSession;
    import org.springframework.web.socket.handler.TextWebSocketHandler;
    
    import com.hncy.optima.websocket.service.MessageWebSocketService;
    
    
    @Component
    public class MessageWebSocketHandler extends TextWebSocketHandler{
    
    protected final static Log log = LogFactory.getLog(MessageWebSocketHandler.class);
    
    private static final Map<String, WebSocketSession> userSocketSessions;
    
    @Autowired
    private MessageWebSocketService messageWebSocketService;
    
    static{
    userSocketSessions = new HashMap<String, WebSocketSession>();
    }
    
    public List<String> getOnlineUsers(){
    
    return new ArrayList<String>(userSocketSessions.keySet());
    }
    
    /**
    * 当用户的链接成功后,获取该用户的消息数,并推送给该用户
    */
    @Override
    public void afterConnectionEstablished(WebSocketSession session)
    throws Exception {
    super.afterConnectionEstablished(session);
    String loginName = (String)session.getAttributes().get("loginName");
    if(userSocketSessions.get(loginName) == null){
    userSocketSessions.put(loginName, session);
    }
    //获取用户的未读信息
    int count = this.messageWebSocketService.getUnReadMessagesCount(loginName);
    
    session.sendMessage(new TextMessage("连接成功"));
    }
    
    /**
    * 当关闭链接后,将用户从用户池中移除
    */
    @Override
    public void afterConnectionClosed(WebSocketSession session,
    CloseStatus status) throws Exception {
    // TODO Auto-generated method stub
    super.afterConnectionClosed(session, status);
    Iterator<Entry<String, WebSocketSession>> it = userSocketSessions.entrySet().iterator();
    while(it.hasNext()){
    Entry<String,WebSocketSession> entry = it.next();
    if(entry.getValue().getId().equals(session.getId())){
    userSocketSessions.remove(entry.getKey());
    break;
    }
    }
    System.out.println("关闭连接");
    
    }
    
    /**
    * 消息处理,在客户端通过WebSocket API发送的消息会进过这里,然后进行相应的处理
    */
    @Override
    protected void handleTextMessage(WebSocketSession session,
    TextMessage message) throws Exception {
    // TODO Auto-generated method stub
    super.handleTextMessage(session, message);
    //如果客户端发送的消息为空,那么直接返回
    if(message.getPayloadLength() == 0)
    return;
    }
    
    public void sendMessageToUser(String loginName,TextMessage message) throws IOException{
    WebSocketSession session = userSocketSessions.get(loginName);
    if(session != null && session.isOpen()){
    session.sendMessage(message);
    }
    }
    
    /**
    * 消息传输错误处理
    */
    @Override
    public void handleTransportError(WebSocketSession session,
    Throwable exception) throws Exception {
    if(session.isOpen()){
    session.close();
    }
    Iterator<Entry<String,WebSocketSession>> it = userSocketSessions.entrySet().iterator();
    while(it.hasNext()){
    Entry<String,WebSocketSession> entry = it.next();
    if(entry.getValue().getId().equals(session.getId())){
    userSocketSessions.remove(entry.getKey());
    break;
    }
    }
    }
    
    /**
    * 向所有在线用户发送消息
    * @param message
    * @throws IOException
    */
    public void sendMessageToAllOnlinUsers(final TextMessage message) throws IOException{
    Iterator<Entry<String,WebSocketSession>> it = userSocketSessions.entrySet().iterator();
    while(it.hasNext()){
    final Entry<String,WebSocketSession> entry = it.next();
    //采用多线程的方式发送消息
    if(entry.getValue().isOpen()){
    new Thread(new Runnable() {
    
    @Override
    public void run() {
    try{
    if(entry.getValue().isOpen()){
    entry.getValue().sendMessage(message);
    }
    }catch(IOException e){
    log.error("多线程发送消息给用户错误,用户:" + entry.getKey(), e);
    }
    }
    }).start();
    }
    }
    System.out.println("发送成功");
    }
    
    /**
    * 将消息发送给指定的用户集合
    * @param loginNames
    * @param message
    * @throws IOException
    */
    public void sendMessageToUsers(List<String> loginNames,final TextMessage message) throws IOException{
    for(String loginName : loginNames){
    final WebSocketSession session = userSocketSessions.get(loginName);
    if(session != null && session.isOpen()){
    new Thread(new Runnable() {
    
    @Override
    public void run() {
    try{
    if(session.isOpen()){
    session.sendMessage(message);
    }
    }catch(IOException e){
    log.error("多线程发送消息给用户错误,用户:" + session.getAttributes().get("loginName"), e);
    }
    }
    }).start();
    }
    }
    }
    }

    我们可以修改其中的内容

    **********************************************

    package com.hncy.optima.websocket.service;
    
    
    public interface MessageWebSocketService {
    
    int getUnReadMessagesCount(String loginName);
    
    }
    
     
    
    package com.hncy.optima.websocket.service.impl;
    
    import org.springframework.stereotype.Component;
    
    import com.hncy.optima.websocket.service.MessageWebSocketService;
    
    
    @Component
    public class MessageWebSocketManagerImpl implements MessageWebSocketService{
    
    /* (non-Javadoc)
    * @see com.optima.websocket.service.MessageWebSocketService#getUnReadMessagesCount(java.lang.String)
    */
    @Override
    public int getUnReadMessagesCount(String loginName) {
    return 0;
    }
    
    }

    *********************************调用发送信息*******************************

    try {
    messageWebSocketHandler.sendMessageToAllOnlinUsers(new TextMessage("hello"));
    } catch (IOException e) {
    e.printStackTrace();
    }

    *********************************注意事项****************************

    之前我用的是spring4.12但是报错了,后来我全部换成了4.16后就不在报错,为了保险起见,建议使用全家福,web,webSocket是必须要的。

    在前台jsp页面,我们可以用http://<%= request.getServerName() %>:<%=request.getServerPort()%>来获取到地址与端口号,我之上写的地址一定要和调用地址相同,不然是不能达成连接的,不过最好的方法就是使用http://<%= request.getServerName() %>:<%=request.getServerPort()%>,就不会再担心这些问题了。

  • 相关阅读:
    JSP中Session的使用
    深入了解父类引用指向子类
    Gamma校正及其OpenCV实现
    cocos2d-x3.0之请求网络(phpserver)
    Quartz使用-入门使用(java定时任务实现)
    ExtJs--15--Ext.is*各种类型推断的方法,简单看源代码就能够明确了
    小谈边界问题
    VS2010旗舰版安装图解
    LSPCI具体解释分析
    兔子--gradle安装和配置
  • 原文地址:https://www.cnblogs.com/handbang/p/6705988.html
Copyright © 2020-2023  润新知