使用server side event 實作聊天功能

王嘉鴻 2017/12/04 17:48:50
909

使用server side event 實作聊天功能


簡介

前端使用server side event搭配Spring SseEmitter,簡簡單單就能夠建立聊天功能

作者

王嘉鴻


1. 前言

    現今越來越多網站有聊天功能或是聊天機器人,這種網頁與Server的互動大致上是使用三種技術來完成。
Ajax Long-Polling、Server Sent Events、Websockets
本章節將以 Server Sent Events為範例簡單完成線上聊天。
 

2. 環境

     IDE: sts-3.7.2.RELEASE
     JDK: 1.8
     Framework: Spring-boot.1.5.7.RELEASE
     Server: tomcat8
     JS: Jquery.1.12.2、EventSource.js

3. 實作

     建立Project之前我們需要先下載兩個部分
3.1 EventSource.js 使用Server-Sent-Event主要檔案,由於原生Server-Sent-Event對IE是不支持的,但有好心人release出一版對IE
https://github.com/Atmosphere/atmosphere/wiki/Adding-Server-Side-Events-Support-in-Internet-Explorer-and-old-Browsers
 
3.2 我們需要一個簡易的畫面
https://github.com/shaadomanthra/facebook-like-chat
 
 
3.3 文章建立Spring-boot專案
開啟STS選擇 NEW->Spring Starter Project->Spring-boot-1.5.7.RELEASE,也可以參考其他文章建立Project
 
Project 結構
 
 
MvcConfig.java-Spring MVC 設定
 
 
ServletInitializer.java-代替web.xml
 
 
LoginController.java-方便測試我們這邊用url來區分腳色
 
 
RegisterController.java-網頁與server建立連結以及傳送訊息
register method: 建立連線
SseEmitter--這是Spring對SSE的Support,回傳SseEmitter物件就可以對網頁做長時間的連線
並將 SseEmitter存放起來(以腳色作為對應)當有訊息我們可以操作他發送訊息
SseEmitter(0L)因為我們是聊天所以使用"0L"代表永遠不逾時
 
pushMessage method: 發送訊息
使用 腳色拿取相對應的 SseEmitter,使用send()方法就可以將訊息推送至網頁端
 
 
jason.jsp、mark.jsp-兩個jsp是一樣只是區分腳色
import js、css
 
 
SSE在網頁端的套版寫法
與Server建立連線 new EventSource('<c:url value = "/register?id="/>' + id);
addEventListener: message
我們回到java那邊 SseEmitter.send(map, MediaType.APPLICATION_JSON); 當沒有指定時defaule為message
你也可以指定你要的值 SseEmitter.send(SseEmitter.event().name("checkChat").data(text, MediaType.TEXT_PLAIN));
在jsp就要新建立一個Listener
source.addEventListener('checkChat', function(e) {
});
addEventListener: open、error
EventSource自訂義 open:連線開啟時、error:連線錯誤
 
 
appendUserMessage: 將收到訊息呈現在網頁上
push: 發送訊息到Server上
 
 
畫面HTML
 
 
script.js-我們修改一下在他發送訊息時放入我們的method
 

4. 測試

     Project準備好後,掛載到tomcatg上執行兩個url
http://127.0.0.1:8080/chatTest/login/mark
http://127.0.0.1:8080/chatTest/login/jason
 
 
 
使用browser為chrome按下F12選到network,你會看到連現狀態SSE只會開一條連線到Server並顯示pedding
 
 

5. 總結

     由於Spring對於SSE的支持操控上面十分便利以及強大
原生的寫法
 
 
你可以看到它是自己幫你做ajax long polling,如果沒有設定延遲時間它一直幫你跟Server做連線以及要資料的行為
與websocket比較雖然SSE只有單向溝通,上面範例可看到發訊息需要自己寫,跟 websocket是雙向溝通是有差別,但因為 websocket 是使用ws:http://....這種方式跟Server溝通遇到proxy server會有問題以及 websocket相對於 SSE複雜龐大,所以在網頁與Server的互動中選擇SSE是一種不錯的選擇。
王嘉鴻
Shayne
2019/05/16 19:59:19

想請教 與Server建立連線 new EventSource('<c:url value = "/register?id="/>' + id);  以及 function 兩段落該寫在哪裡?