SpringMVC整合webScoket总结

运行环境tomcat7以上

1.创建@ServerEndpoint注解类

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;
import javax.websocket.CloseReason;
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;

@ServerEndpoint(value="/echo",configurator=GetHttpSessionConfigurator.class)
public class EndPointServer {

    public static  List  sessionList= new ArrayList();
    public Session  session ;

     @OnOpen
     public void onOpen(Session session,EndpointConfig config) throws IOException {
         //以下代码省略...
        System.out.println("用户"+session.getId()+"链接");
        this.session = session;
        sessionList.add(this);
        HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        httpSession.setAttribute("scoketSessionId", session.getId()); 
    }

     @OnMessage
     public void onMessage(Session session,String message) {
     }

     @OnError
     public void onError(Throwable t) {
         //以下代码省略...
         System.err.println("出错了");
     }

     @OnClose
     public void onClose(Session session, CloseReason reason) {
         //以下代码省略...
         sessionList.remove(this);
         System.out.println(session.getId()+"退出链接");
     } 


}

OnOpen、OnClose、OnError、OnMessage分别是前端发起链接、关闭链接、出错时、发送消息时的响应事件

configurator用于客户端建立长连接时可以获取httpsession,另外该动作还需要一个ServletRequest监听器和一个ServerEndpointConfig.Configurator子类,如果缺少则会出现httpsession空指针异常。

1)以下是ServletRequest监听器

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;

@WebListener
public class RequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void requestInitialized(ServletRequestEvent arg0) {
         ((HttpServletRequest) arg0.getServletRequest()).getSession();

    }

}

另外web.xml配置监听器

<listener>
        <listener-class>包名路径.RequestListenerlistener-class>
 listener>

2)以下是ServerEndpointConfig.Configurator子类

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;


/** * scoket获取session * @author Administrator * */
public class GetHttpSessionConfigurator extends Configurator {

    @Override
    public void modifyHandshake(ServerEndpointConfig sec,
            HandshakeRequest request, HandshakeResponse response) {
        // TODO Auto-generated method stub
         HttpSession httpSession=(HttpSession) request.getHttpSession();
         sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }



}

2.前端H5 发起webscoket长连接 js代码


<html>
<head>
<meta charset="UTF-8">
<title>WebScoketAPItitle>
head>
<body>
<input type="text" id='msg'/>
<button onclick='tosend()'>发送button>
<button>退出button>
<br>
<textarea id='mymess'>textarea>
body>
<script type="text/javascript" src="js/jquery-1.8.3.min.js">script>
<script type="text/javascript"> var ws = new WebSocket("ws://localhost:8080/WeChatService/echo"); ws.onmessage = function(evt){ console.log(evt.data); $("#mymess").append(evt.data+"
"
); }; ws.onerror = function(evt){ console.log("WebSocketError"); }; /* ws.onopen = function(){ ws.send(msg); }; ws.onclose = function(evt){ console.log("WebSocketClosed"); }; */ function tosend(){ var msg=$("#msg").val(); $("#mymess").append(msg+"
"
); ws.send(msg); }
script> html>

主要创建WebSocket对象与服务器握手,握手后就会处于长链接状态,当服务器有推送的消息进来时,前端的onmessage方法就会触发

3.使用springMVC 访问URL对某个session推送消息

代码如下:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xjt.util.JsonUtil;

/** * 推送控制层 * @author Administrator * */
@Controller
public class PushController {

     /** * 查询所有在线人员的sid * @param modelMap * @param session * @return */
     @ResponseBody
     @RequestMapping("getAllOnline")
     public String getAllOnline(ModelMap modelMap,HttpSession session){
         List ids=new ArrayList();
         for (EndPointServer endPointServer : EndPointServer.sessionList) {
             ids.add(endPointServer.session.getId());
         }
         modelMap.put("ids", ids);
         return JsonUtil.toJson(modelMap);
     }

     /** * 向用户发送消息 * @param modelMap * @param session * @param sid * @param msg * @return */
     @ResponseBody
     @RequestMapping("toSendMsg")
     public String toSendMsg(ModelMap modelMap,HttpSession session,String sid,String msg){
         if (sid!=null&&sid.length()>0&&msg!=null&&msg.length()>0) {
             for (EndPointServer endPointServer : EndPointServer.sessionList) {
                 if (sid.equals(endPointServer.session.getId())) {
                     try {
                            endPointServer.session.getBasicRemote().sendText(msg);
                            modelMap.put("msg", 1);//发送成功
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            modelMap.put("msg", 0);//发送失败
                            e.printStackTrace();
                        }
                 }

            }
         }else {
             modelMap.put("msg", -1);//参数错误
        }

         return JsonUtil.toJson(modelMap);
     }


     /** * 广播发送消息 * @param modelMap * @param session * @param msg * @return */
     @ResponseBody
     @RequestMapping("toBroadCastMsg")
     public String toBroadCastMsg(ModelMap modelMap,HttpSession session,String msg){
         if (msg!=null&&msg.length()>0) {
             for (EndPointServer endPointServer : EndPointServer.sessionList) {
                 try {
                        endPointServer.session.getBasicRemote().sendText(msg);
                        modelMap.put("msg", 1);//发送成功
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        modelMap.put("msg", 0);//发送失败
                        e.printStackTrace();
                    }           
            }
         }else {
             modelMap.put("msg", -1);//参数错误
        }

         return JsonUtil.toJson(modelMap);
     }

     /** * 查询所有sid * @param modelMap * @param session * @return */
     @ResponseBody
     @RequestMapping("getScoketSessionId")
     public String getScoketSessionId(ModelMap modelMap,HttpSession session){
         if (session.getAttribute("scoketSessionId")!=null) {
             modelMap.put("sid", session.getAttribute("scoketSessionId"));
         }else {
            modelMap.put("sid", "null");
         }
         return JsonUtil.toJson(modelMap);
     }


}

发送消息主要通过websocket.Session类的getBasicRemote().sendText()方法进行推送。

以上代码可以根据需要进行修改,比如分组等、sessionId与业务逻辑实际用户关联,因为可以获取用户的httpsession那么可以做的事情就很多了。

以上代码的汇总来自以下链接,感谢以下资料的提供者:

WebSocket实战
WebSocket之获取HttpSession
Websocket - httpSession returns null
尚学堂_高明鑫史上最易懂Websocket视频教程

你可能感兴趣的:(java)