Flutter websocket 實現訊息推送

leyan發表於2018-07-09

沒什麼可說的,直接上程式碼吧

  • Flutter 中的訊息管理工具:
class MessageUtils {
  static WebSocket _webSocket;
  static num _id = 0;

  static void connect() {
    Future<WebSocket> futureWebSocket =
        WebSocket.connect(Api.WS_URL + "/leyan");// Api.WS_URL 為伺服器端的 websocket 服務
    futureWebSocket.then((WebSocket ws) {
      _webSocket = ws;
      _webSocket.readyState;
      // 監聽事件
      void onData(dynamic content) {
        _id++;
        _sendMessage("收到");
        _createNotification("新訊息", content + _id.toString());
      }

      _webSocket.listen(onData,
          onError: (a) => print("error"), onDone: () => print("done"));
    });
  }

  static void closeSocket() {
    _webSocket.close();
  }

  // 向伺服器傳送訊息
  static void _sendMessage(String message) {
    _webSocket.add(message);
  }

  // 手機狀態列彈出推送的訊息
  static void _createNotification(String title, String content) async {
    await LocalNotifications.createNotification(
      id: _id,
      title: title,
      content: content,
      onNotificationClick: NotificationAction(
          actionText: "some action",
          callback: _onNotificationClick,
          payload: "接收成功!"),
    );
  }

  static _onNotificationClick(String payload) {
    LocalNotifications.removeNotification(_id);
    _sendMessage("訊息已被閱讀");
  }
}
複製程式碼
  • websocket 服務:
@ServerEndpoint(value = "/api/ws/{userid}")// 對應 Api.WS_URL
@Component
public class SocketServer {

    private Session session;
    private static Map<String, Session> sessionPool = new HashMap<>();
    private static Map<String, String> sessionIds = new HashMap<>();

    private static Map<String, TreeSet<String>> remainingMessagePool = new HashMap<>(128);

    /**
     * 使用者連線時觸發
     *
     * @param session
     * @param userid
     */
    @OnOpen
    public void open(Session session, @PathParam(value = "userid") String userid) {
        this.session = session;
        sessionPool.put(userid, session);
        sessionIds.put(session.getId(), userid);
        // 離線訊息傳送
        if (remainingMessagePool.get(userid) != null) {
            TreeSet<String> remainingMessages = remainingMessagePool.get(userid);
            remainingMessages.forEach(it -> sendMessage(it, userid));
            remainingMessagePool.remove(userid);
        }
    }

    /**
     * 收到資訊時觸發
     *
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        System.out.println("傳送人:" + sessionIds.get(session.getId()) + "內容:" + message);
    }

    /**
     * 連線關閉觸發
     */
    @OnClose
    public void onClose() {
        sessionPool.remove(sessionIds.get(session.getId()));
        sessionIds.remove(session.getId());
    }

    /**
     * 發生錯誤時觸發
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    /**
     * 資訊傳送的方法
     *
     * @param message
     * @param userId
     */
    public static void sendMessage(String message, String userId) {
        Session s = sessionPool.get(userId);
        if (s != null) {
            try {
                s.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            // 離線訊息儲存
            if (remainingMessagePool.get(userId) != null) {
                TreeSet<String> remainingMessages = remainingMessagePool.get(userId);
                remainingMessages.add(message);
            } else {
                TreeSet<String> remainingMessages = new TreeSet<>();
                remainingMessages.add(message);
                remainingMessagePool.put(userId, remainingMessages);
            }
        }
    }

    /**
     * 獲取當前連線數
     *
     * @return
     */
    public static int getOnlineNum() {
        return sessionPool.size();
    }

    /**
     * 獲取線上使用者名稱以逗號隔開
     *
     * @return
     */
    public static String getOnlineUsers() {
        StringBuffer users = new StringBuffer();
        for (String key : sessionIds.keySet()) {
            users.append(sessionIds.get(key) + ",");
        }
        return users.toString();
    }

    /**
     * 資訊群發
     *
     * @param msg
     */
    public static void sendAll(String msg) {
        for (String key : sessionIds.keySet()) {
            sendMessage(msg, sessionIds.get(key));
        }
    }

    /**
     * 多個人傳送給指定的幾個使用者
     *
     * @param msg
     * @param persons 使用者s
     */

    public static void SendMany(String msg, String[] persons) {
        for (String userid : persons) {
            sendMessage(msg, userid);
        }

    }
}
複製程式碼

相關文章