webSocket 消息推送

来源:互联网 发布:在淘宝网上卖东西 编辑:程序博客网 时间:2024/05/29 04:50

结构

前端 –> 消息推送系统 –>后端

实现方式

消息推送系统的搭建

  • socketJQ.js
window.onload = function () {    var websocket = null;    if(username == null || appType == null){        username = 'test';        appType= 'test';    }//判断当前浏览器是否支持WebSocket    if ('WebSocket' in window) {        websocket = new WebSocket("ws://localhost:9090/websocket/"+username+"/"+appType+"");    }    else {        alert('Not support websocket')    }//连接发生错误的回调方法    websocket.onerror = function () {        setMessageInnerHTML("error_______");    };//连接成功建立的回调方法    websocket.onopen = function (event) {        setMessageInnerHTML("open");    };//接收到消息的回调方法    websocket.onmessage = function (event) {        setMessageInnerHTML(event.data);    };//连接关闭的回调方法    websocket.onclose = function () {        setMessageInnerHTML("close________");    };//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。    window.onbeforeunload = function () {        websocket.close();    };//将消息显示在网页上    function setMessageInnerHTML(innerHTML) {        socketMessage(innerHTML)    }//关闭连接    function closeWebSocket() {        websocket.close();    }//发送消息    function send() {        var message = document.getElementById('text').value;        websocket.send(message);    }}
import com.alibaba.fastjson.JSONObject;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.io.IOException;import java.net.URI;import java.util.HashMap;import java.util.Map;@ServerEndpoint(value = "/websocket/{username}/{appType}")@Controller@ClientEndpointpublic class WebSocketController {    private static Map<Object,Map<Object,WebSocketController>> staticMap = new HashMap<>();    /**     * 与某个客户端的连接会话,需要通过它来给客户端发送数据     */    private Session session;    /**     * 通过建立长连接的方式实现后台为前台的消息推送     * @return     */    @RequestMapping("/send_1")    @ResponseBody    public String sendMessage() {        try {            this.session =                    ContainerProvider.getWebSocketContainer()                            .connectToServer(this,                                    new URI(                                            "WS",                                            null,                                            "localhost",                                            8080,                                            "/websocket",                                            null,                                            null));            System.out.println(session.getId());            Map<String, Object> map = new HashMap<>();            map.put("message","你好");            map.put("id","12");            session.getBasicRemote().sendText(JSONObject.toJSONString(map));        } catch (Exception e) {            e.printStackTrace();        }        return "success";    }    /**     * 通过Http请求调用该接口,发送消息     * @param message   消息内容     * @param username  发送给指定的用户     * @param appType   消息的类型     * @return  发送状态     */    @RequestMapping("/send")    @ResponseBody    public String sendMessage( @PathParam(value = "message") String message,                               @PathParam(value = "username") String username,                               @PathParam(value = "appType") String appType) {        try {            staticMap.get(username).get(appType).sendMessage(message);        } catch (IOException e) {            e.printStackTrace();        }        return "success";    }    /**     * @param model     * @param username     * @param appType     * @return     */    @RequestMapping("/httpwebsocket/{username}/{appType}")    public String index(            Model model,@PathParam(value = "username") String username, @PathParam(value = "appType") String appType) {        Map<String,String> resultMap = new HashMap<>();        resultMap.put("username",username);        resultMap.put("appType",appType);        model.addAttribute("resultMap",resultMap);        return "httpwebsocket";    }    /**     * 连接建立成功调用的方法     *     * @param session     */    @OnOpen    public void onOpen(            @PathParam(value = "username") String username, @PathParam(value = "appType") String appType, Session session) {        System.out.println(username + appType);        this.session = session;        Map<Object,WebSocketController> map = new HashMap<>();        map.put(appType,this);        staticMap.put(username,map);    }    /**     * 连接关闭调用的方法     */    @OnClose    public void onClose() {        for (Object key : staticMap.keySet()) {            Map<Object, WebSocketController> objectObjectMap = staticMap.get(key);            for (Object mapKey : objectObjectMap.keySet()) {                if(objectObjectMap.get(mapKey).equals(this)){                    staticMap.remove(key);                    continue;                }            }        }    }    /**     * 收到客户端消息后调用的方法     *     * @param message 客户端发送过来的消息     */    @OnMessage    public void onMessage(String message, Session session) throws NoSuchFieldException, IllegalAccessException {        System.out.println("来自客户端的消息:" + message);    }    /**     * 发生错误时调用     */    @OnError    public void onError(Session session, Throwable error) {        System.out.println("发生错误");        error.printStackTrace();    }    public void sendMessage(String message) throws IOException {        this.session.getBasicRemote().sendText(message);    }    /**     * 群发自定义消息     */    public static void sendInfo(String message) throws IOException {    }}
  • pom.xml
<parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.6.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>        <java.version>1.8</java.version>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>            <exclusions>                <exclusion>                    <groupId>org.springframework.boot</groupId>                    <artifactId>spring-boot-starter-tomcat</artifactId>                </exclusion>            </exclusions>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-thymeleaf</artifactId>        </dependency>        <dependency>            <groupId>javax</groupId>            <artifactId>javaee-api</artifactId>            <version>7.0</version>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-websocket</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-security</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>1.2.22</version>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build>

使用

  • 前端
    必须先提供username和apptype的值.并且提供自己的业务逻辑方法名为socketMessage(message),然后引入socketJQ.js,注意这里的顺序.
    例如:
<script type="text/javascript">        var username = '123';        var appType= '456';        function socketMessage(message) {            alert(message)        }    </script>    <script src="http://localhost:9090/socketJQ.js"></script>
原创粉丝点击