1. 程式人生 > >springboot + websocket

springboot + websocket

1.引入pom依賴

  1. <dependency>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-starter-websocket</artifactId>

  4. </dependency>

2.新建websocket的服務

WebSocketServer.java
  1. /**

  2. * @Author: wyb

  3. * @Date: 2018/7/12 20:04

  4. * @Description:websoceket具體業務實現

  5. */

  6. @ServerEndpoint(value = "/websocket")

  7. @Component

  8. public class WebSocketServer {

  9. private final Logger logger = LoggerFactory.getLogger(this.getClass());

  10. //靜態變數,用來記錄當前線上連線數。應該把它設計成執行緒安全的。

  11. private static int onlineCount = 0;

  12. //concurrent包的執行緒安全Set,用來存放每個客戶端對應的MyWebSocket物件。

  13. private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

  14. //與某個客戶端的連線會話,需要通過它來給客戶端傳送資料

  15. private Session session;

  16. /**

  17. * 連線建立成功呼叫的方法*/

  18. @OnOpen

  19. public void onOpen(Session session) {

  20. this.session = session;

  21. webSocketSet.add(this); //加入set中

  22. addOnlineCount(); //線上數加1

  23. }

  24. /**

  25. * 連線關閉呼叫的方法

  26. */

  27. @OnClose

  28. public void onClose() {

  29. webSocketSet.remove(this); //從set中刪除

  30. subOnlineCount(); //線上數減1

  31. }

  32. /**

  33. * 收到客戶端訊息後呼叫的方法

  34. *

  35. * @param message 客戶端傳送過來的訊息*/

  36. @OnMessage

  37. public void onMessage(String message, Session session) {

  38. System.out.println("來自客戶端的心跳:" + message);

  39. }

  40. /**

  41. * 發生錯誤時呼叫

  42. @OnError

  43. **/

  44. public void onError(Session session, Throwable error) {

  45. if(error != null)

  46. logger.error("WebSocketServer onError:" + error.getMessage());

  47. }

  48. /***

  49. * 對單一客戶傳送推送訊息

  50. * @param message 訊息內容

  51. */

  52. public void sendMessage(String message){

  53. try{

  54. this.session.getBasicRemote().sendText(message);

  55. }catch (Exception ex){

  56. logger.error("WebSocketServer sendMessage:" + ex.getMessage());

  57. }

  58. }

  59. /**

  60. * 群發自定義訊息

  61. * */

  62. public static void broadcastSendInfo(String message){

  63. try{

  64. for (WebSocketServer item : webSocketSet) {

  65. item.sendMessage(message);

  66. }

  67. }catch (Exception ex){

  68. System.out.println(ex.getMessage());

  69. }

  70. }

  71. public static synchronized void addOnlineCount() {

  72. WebSocketServer.onlineCount++;

  73. }

  74. public static synchronized void subOnlineCount() {

  75. WebSocketServer.onlineCount--;

  76. }

  77. }

3.向spring注入bean

  1. @Bean

  2. public ServerEndpointExporter serverEndpointExporter() {

  3. return new ServerEndpointExporter();

  4. }

4.新增websocket的js

MyWebSocket.js
  1. /**

  2. * Created by PC on 2018/2/11.

  3. */

  4. var heartflag = true;

  5. var webSocket = null;

  6. var tryTime = 0;

  7. $(function () {

  8. initSocket();

  9. });

  10. /**

  11. * 初始化websocket,建立連線

  12. */

  13. function initSocket() {

  14. if (!window.WebSocket) {

  15. alert("您的瀏覽器不支援推送功能");

  16. return false;

  17. }

  18. webSocket = null;

  19. webSocket = new WebSocket("ws://" + window.location.host + "/websocket");

  20. // 收到服務端訊息

  21. webSocket.onmessage = function (msg) {

  22. if(msg.data == "&"){

  23. // 暫時不用伺服器反向傳送心跳

  24. }else{

  25. popmsg(msg.data);

  26. }

  27. };

  28. // 異常

  29. webSocket.onerror = function (event) {

  30. heartflag = false;

  31. };

  32. // 建立連線

  33. webSocket.onopen = function (event) {

  34. heartflag = true;

  35. heart();

  36. tryTime = 0;

  37. };

  38. // 斷線重連

  39. webSocket.onclose = function () {

  40. heartflag = false;

  41. tryTime++;

  42. // 重試10次,每次之間間隔1秒

  43. if (tryTime < 10) {

  44. setTimeout(function () {

  45. if(!heartflag){

  46. webSocket = null;

  47. initSocket();

  48. //alert("第:" + tryTime + "次重新建鏈。");

  49. }

  50. }, 1000);

  51. } else {

  52. //alert("重連失敗.");

  53. }

  54. };

  55. heartflag = true;

  56. }

  57. // 連線成功後傳送心跳

  58. function heart() {

  59. if (heartflag){

  60. webSocket.send("&");

  61. }

  62. setTimeout("heart()", 10*1000);

  63. }

  64. function popmsg(popmsg){

  65. //配置一個透明的詢問框

  66. layer.msg('', {

  67. time: 20000, //20s後自動關閉

  68. offset: 'rb',

  69. content: '<div style="padding: 20px 100px;">'+ popmsg +'</div>'

  70. });

  71. }

這裡顯示使用了layer的部分內容

請注意最好建立心跳,因為如果不建立心跳那麼網路中存在問題將有可能無法發現線路斷鏈。