實現一對一聊天功能
功能介紹:實現A和B單獨聊天功能,即A發消息給B只能B接收,同樣B向A發消息只能A接收。
本篇博客是在上一遍基礎上搭建,上一篇博客地址:【WebSocket】---實現游戲公告功能。底部有源碼。
先看演示效果:
一、案例解析
1、PTPContoller
/** * 功能描述:簡單版單人聊天 * 這里沒有用到@SendTo("/topic/game_chat")來指定訂閱地址,而是通過SimpMessagingTemplate來指定 */ @Controller public class PTPContoller { @Autowired private WebSocketService ws; @MessageMapping("/ptp/single/chat") public void singleChat(InMessage message) { ws.sendChatMessage(message); } }
這里和前面的公告消息,最大的區別就是接口上沒有通過@SendTo("/topic/game_chat")來發送消息。
(1)@SendTo和SimpMessagingTemplate區別
spring websocket基於注解的@SendTo和@SendToUser雖然方便,但是有局限性,例如我這樣子的需求,我想手動的把消息推送給某個人,或者特定一組人,怎么辦,
@SendTo只能推送給所有人(它是一個具體地址,一點都不靈活),@SendToUser只能推送給請求消息的那個人,這時,我們可以利用SimpMessagingTemplate這個類
SimpMessagingTemplate有倆個推送的方法
convertAndSend(destination, payload); //將消息廣播到特定訂閱路徑中,類似@SendTo convertAndSendToUser(user, destination, payload);//將消息推送到固定的用戶訂閱路徑中,類似@SendToUser
2、WebSocketService
import com.jincou.websocket.model.InMessage; import com.jincou.websocket.model.OutMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service; /** * 功能描述:簡單消息模板,用來推送消息 */ @Service public class WebSocketService { @Autowired private SimpMessagingTemplate template; /** * 簡單點對點聊天室 */ public void sendChatMessage(InMessage message) { //可以看出template最大的靈活就是我們可以獲取前端傳來的參數來指定訂閱地址 //前面參數是訂閱地址,后面參數是消息信息 template.convertAndSend("/chat/single/"+message.getTo(), new OutMessage(message.getFrom()+" 發送:"+ message.getContent())); }
3、app.js
其它地方和公告的app.js一樣,只有下面兩點做了一點修改
function connect() { var from = $("#from").val(); var socket = new SockJS('/endpoint-websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected(true); console.log('Connected: ' + frame); //1、通過+from就可以靈活的用當前用戶的某一信息來指定該用戶訂閱地址。 stompClient.subscribe('/chat/single/'+from, function (result) { showContent(JSON.parse(result.body)); }); }); } function sendName() { //2、這里出了發送content信息外,還發送了發送者用戶信息,和接受者的信息 stompClient.send("/app/ptp/single/chat", {}, JSON.stringify({'content': $("#content").val(), 'to':$("#to").val(), 'from':$("#from").val()})); }
4、user.html
其它地方也和之前公告的一樣,下面是修改的地方
<div class="col-md-6"> <form class="form-inline"> <div class="form-group"> <input type="text" id="from" class="form-control" placeholder="我是"> <input type="text" id="to" class="form-control" placeholder="發送給誰"> <input type="text" id="content" class="form-control" placeholder="請輸入..."> </div> <button id="send" class="btn btn-default" type="submit">發送</button> </form> </div>
5、再把整個思路縷一縷
以 A 向 B 發送消息為例
(1)form輸入框輸入:“A”,to輸入框輸入 “B” 點擊“Connect”建立websocket連接
(2)那么的 A 用戶的訂閱地址就是'/chat/single/A'
(3)前端在“content”按鈕中輸入“你今天吃雞了嗎?”,再點擊“發送”按鈕
(4)后台通過接受處理就成了:
template.convertAndSend("/chat/single/B",new OutMessage(" A 發送:你今天吃雞了嗎?"));
那么 B 向 A 發送性質一模一樣。就可以實現一對一聊天。
注意:這個只是演示,並不是真正一對一聊天,一般如果實現一對一聊天,那么form和to都應該是唯一的,比如該用戶的userID,這樣就可以真正實現一對一聊天了。
gitHub源碼:https://github.com/yudiandemingzi/spring-boot-websocket-study
想太多,做太少,中間的落差就是煩惱。想沒有煩惱,要么別想,要么多做。中校【19】