websocket 实时推送通知公告

需求: 后台新增消息通知公告,并实时推送给客户端,好像用websocket可以很方便的解决这个问题,但是websocket有个弊端不兼容IE8,9后面查阅一些大牛博客,好像可以用web-socket-js  解决兼容性问题,这里也用了web-sokcet-js具体结果还需要测试

小小流程图

代码:

     客户端

web-socket-js


<html><head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Sample of web_socket.js</title>
  
  <!-- Include these three JS files: -->
  <script type="text/javascript" src="swfobject.js"></script>
  <script type="text/javascript" src="web_socket.js"></script>

  <script type="text/javascript">
    
    // Set URL of your WebSocketMain.swf here:
    WEB_SOCKET_SWF_LOCATION = "WebSocketMain.swf";
    // Set this to dump debug message from Flash to console.log:
    WEB_SOCKET_DEBUG = true;
    
    // Everything below is the same as using standard WebSocket.
    
    var ws;
    
    function init() {

      // Connect to Web Socket.
      // Change host/port here to your own Web Socket server.
      ws = new WebSocket("ws://localhost:9002/websocketserver/websocket");

      // Set event handlers.
      ws.onopen = function() {
        output("onopen");
      };
      ws.onmessage = function(e) {
        // e.data contains received string.
        output("onmessage: " + e.data);
      };
      ws.onclose = function() {
        output("onclose");
      };
      ws.onerror = function() {
        output("onerror");
      };

    }
    
    function onSubmit() {
      var input = document.getElementById("input");
      // You can send message to the Web Socket using ws.send.
      ws.send(input.value);
      output("send: " + input.value);
      input.value = "";
      input.focus();
    }
    
    function onCloseClick() {
      ws.close();
    }
    
    function output(str) {
      var log = document.getElementById("log");
      var escaped = str.replace(/&/, "&amp;").replace(/</, "&lt;").
        replace(/>/, "&gt;").replace(/"/, "&quot;"); // "
      log.innerHTML = escaped + "<br>" + log.innerHTML;
    }

  </script>
</head><body οnlοad="init();">
  <form οnsubmit="onSubmit(); return false;">
    <input type="text" id="input">
    <input type="submit" value="Send">
    <button οnclick="onCloseClick(); return false;">close</button>
  </form>
  <div id="log"></div>
</body></html>

服务端

    pom.xml

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>

websocket配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * websocket配置
 * @author xzx
 */
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter getServerEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

websocket服务

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * websocketserver
 * @author
 */
@Slf4j
@ServerEndpoint(value = "/websocket")
@Component
public class WebSocketServer {
    /**
     * 静态变量,用来记录当前连接数,应该是线程安全的
     */
    private static int onLineCount = 0;
    /**
     * concurrent包下线程安全的set,用来存放每个客户端对应的websocketserver
     */
    private static CopyOnWriteArraySet<WebSocketServer> socketServers = new CopyOnWriteArraySet<>();
    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 建立连接调用的方法
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        //加入到session中
        socketServers.add(this);
        //连接数加1
        addOnLine();
        log.info("有新连接加入!当前连接数为:"+getLineCount());
        try {
            sendMessage("连接成功");
        }catch (IOException e){
            log.error("websocket IO异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        socketServers.remove(this);
        subOnLineCount();
        log.info("有一个连接关闭,当前连接数为:"+getLineCount());
    }

    /**
     * 客户端发送消息调用的方法
     * @param message
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        log.info("来自客户端的消息:"+message);
        for (WebSocketServer webSocketServer : socketServers) {
            webSocketServer.sendMessage(message);
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 群发自定义消息
     * */
    public static void sendInfo(String message)  {
        log.info(message);
        for (WebSocketServer item : socketServers) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    private static synchronized void subOnLineCount() {
        onLineCount--;
    }

    private void sendMessage(String string) throws IOException {
        this.session.getBasicRemote().sendText(string);
    }

    private static synchronized int getLineCount() {
        return onLineCount;
    }

    private static synchronized void addOnLine() {
        onLineCount++;
    }
}

服务端推送消息给客户端


    @RequestMapping("/add")
    @ResponseBody
    public ResultBean add(NongjiTMessage nongjiTMessage) {
        nongjiTMessage.setContent("无论走到哪,都要记住过去都是假的," +
                            "回忆是一条没有归途的路,以往的一切春天都无法复原," +
                        "即使最狂热最坚贞的爱情,归根结底也不过是一种瞬息即逝的现实," +
                                            "唯有孤独永恒。");
        nongjiTMessage.setStatus(0);
        nongjiTMessage.setCreateTime(TimeUtils.GetNowDate("yyyy-MM-dd HH:mm:ss"));
        nongjiTMessage.setUpdateTime(TimeUtils.GetNowDate("yyyy-MM-dd HH:mm:ss"));
        boolean i = messageService.save(nongjiTMessage);
        if (i) {
            //并且把未读的消息数量返回给websocket客户端
            QueryWrapper<NongjiTMessage> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status",0);
            int count = messageService.count(queryWrapper);
            WebSocketServer.sendInfo(String.valueOf(count));
            return new ResultBean("保存成功");
        } else {
            return new ResultBean("保存失败");
        }
    }
发布了10 篇原创文章 · 获赞 6 · 访问量 186

猜你喜欢

转载自blog.csdn.net/xzx19930928/article/details/104014049