1. 程式人生 > >SpringBoot WebSocket 實現簡單的聊天功能

SpringBoot WebSocket 實現簡單的聊天功能

前言

什麼是WebSocket

WebSocket為瀏覽器和伺服器之間提供了雙工非同步通訊功能,也就是說我們可以利用瀏覽器給伺服器傳送訊息,伺服器也可以給瀏
覽器傳送訊息,目前主流瀏覽器的主流版本對WebSocket的支援都算是比較好的,但是在實際開發中使用WebSocket工作量會略大,
而且增加了瀏覽器的相容問題,這種時候我們更多的是使用WebSocket的一個子協議stomp,利用它來快速實現我們的功能。OK,
關於WebSocket我這裡就不再多說,我們主要看如何使用,如果小夥伴們有興趣可以檢視這個回答來了解更多關於WebSocket的信
息WebSocket 是什麼原理?為什麼可以實現持久連線。

後端

依賴

開啟WebSocket基礎功能

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

配置

新增一個WebSocketConfig類,繼承AbstractWebSocketMessageBrokerConfigurer,定義全域性的配置資訊,使用SpringgBoot推薦的註解配置即JavaConfig形式。

package hello;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import
org.springframework.web.socket.config.annotation.StompEndpointRegistry; /** * Author: Starry.Teng * Email: [email protected] * Date: 17-9-12 * Time: 下午12:57 * Describe: WebSocketConfig */ @Configuration @EnableWebSocketMessageBroker //通過EnableWebSocketMessageBroker 開啟使用STOMP協議來傳輸基於代理(message broker)的訊息,此時瀏覽器支援使用@MessageMapping 就像支援@RequestMapping一樣 public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { //配置訊息代理(message broker) 設定訊息連線請求的各種規範 config.enableSimpleBroker("/topic");//客戶端訂閱地址的字首資訊 config.setApplicationDestinationPrefixes("/app");//客戶端給服務端發訊息的地址的字首 } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { //註冊一個名字為"gs-guide-websocket" 的endpoint,並指定 SockJS協議;新增一個服務端點,來接收客戶端的連線 registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS(); } }

業務邏輯

/**
 * Author: Starry.Teng
 * Email: [email protected]
 * Date: 17-9-12
 * Time: 下午12:57
 * Describe: GreetingController
 */
@Controller
public class GreetingController {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;


    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + message.getName() + "!");
    }

    @MessageMapping("/message")
    //@SendTo("/topic/greetings")
    //接收/app/message發來的value,然後將value轉發到/topic/greetings客戶端
    public Greeting message(String message) throws Exception{
        //通過convertAndSendToUser 向用戶傳送資訊,
        // 第一個引數是接收訊息的使用者,第二個引數是瀏覽器訂閱的地址,第三個引數是訊息本身
        //messagingTemplate.convertAndSendToUser();
        messagingTemplate.convertAndSend("/topic/greetings",new Greeting(message));
        return null;
    }

說明:
1. @MessageMapping註解不是@RequestMapping,後者是我們熟悉的用於http請求的對映,前者是基於webSocket協議的請求。但是理解都很簡單。
2. SimpMessagingTemplate
SimpMessagingTemplate是Spring-WebSocket內建(就是封裝起來的和SDR差不多,很方便)的一個訊息傳送工具,可以將訊息傳送到指定的客戶端。
3. @SendTo這個註解就是將資訊分發到訂閱者 ,和messagingTemplate.convertAndSend()等價。

前端

在resources目錄下新建一個static目錄(springBoot預設路徑),在static下新建index.html和app.js

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Hello WebSocket</title>
    <link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/main.css" rel="stylesheet">
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
    <script src="/app.js"></script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
    enabled. Please enable
    Javascript and reload this page!</h2></noscript>
<div id="main-content" class="container">
    <div class="row">
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="connect">WebSocket connection:</label>
                    <button id="connect" class="btn btn-default" type="submit">Connect</button>
                    <button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect
                    </button>
                </div>
            </form>
        </div>
        <div class="col-md-6">
            <form class="form-inline">
                <div class="form-group">
                    <label for="name">What is your name?</label>
                    <input type="text" id="name" class="form-control" placeholder="Your name here...">
                </div>
                <button id="send" class="btn btn-default" type="submit">Send</button>
            </form>
        </div>
    </div>
    <div class="row">
        <div class="col-md-12">
            <table id="conversation" class="table table-striped">
                <thead>
                <tr>
                    <th>Greetings</th>
                </tr>
                </thead>
                <tbody id="greetings">
                </tbody>
            </table>
        </div>
        <div class="col-md-12">
            <label>write message:</label>
            <input type="text" name="mysend" id="mysend"/>
            <button id="mybutton" value="send">傳送</button>
        </div>
    </div>
    </form>
</div>
</body>
</html>

app.js

var stompClient = null;

function setConnected(connected) {
    $("#connect").prop("disabled", connected);
    $("#disconnect").prop("disabled", !connected);
    if (connected) {
        $("#conversation").show();
    }
    else {
        $("#conversation").hide();
    }
    $("#greetings").html("");
}

function connect() {
    var socket = new SockJS('/gs-guide-websocket'); //構建一個SockJS物件
    stompClient = Stomp.over(socket); //用Stomp將SockJS進行協議封裝
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        /**
 訂閱了/topic/greetings 傳送的訊息,這裡雨在控制器的 convertAndSendToUser 定義的地址保持一致,

         *  這裡多用了一個/user,並且這個user 是必須的,使用user 才會傳送訊息到指定的使用者。

         *  */
        stompClient.subscribe('/topic/greetings', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

function disconnect() {
    if (stompClient !== null) {
        stompClient.disconnect();
    }
    setConnected(false);
    console.log("Disconnected");
}

function sendName() {
    /*訊息傳送*/
    stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}

function showGreeting(message) {
    $("#greetings").append("<tr><td>" + message + "</td></tr>");
}

function sendMessage() {
    stompClient.send("/app/message", {}, JSON.stringify({'message': $("#mysend").val()}));
}

$(function () {
    $("form").on('submit', function (e) {
        e.preventDefault();
    });
    $( "#connect" ).click(function() { connect(); });
    $( "#disconnect" ).click(function() { disconnect(); });
    $( "#send" ).click(function() { sendName(); });
    $( "#mybutton").click(function (){
        sendMessage();
    });
});

說明:
1. 重要的我app.js已經註釋了,其他的就是js能力了
2. 說一下sockjs.js和stomp.js

SockJS:
SockJS 是一個瀏覽器上執行的 JavaScript 庫,如果瀏覽器不支援 WebSocket,該庫可以模擬對 WebSocket 的支援,實現瀏覽器和 Web 伺服器之間低延遲、全雙工、跨域的通訊通道。
Stomp
Stomp 提供了客戶端和代理之間進行廣泛訊息傳輸的框架。Stomp 是一個非常簡單而且易用的通訊協議實現,儘管代理端的編寫可能非常複雜,但是編寫一個 Stomp 客戶端卻是很簡單的事情,另外你可以使用 Telnet 來與你的 Stomp 代理進行互動。

驗證

$ mvn clean package spring-boot:run

瀏覽器:http://localhost:8080/ ,點選connect,輸入使用者可以聊天了,請看下面截圖:
登入
這裡寫圖片描述
在瀏覽器新開tab頁面
這裡寫圖片描述
這裡寫圖片描述
成功對不對。

後記

參考文章

相關推薦

SpringBoot WebSocket 實現簡單聊天功能

前言 什麼是WebSocket WebSocket為瀏覽器和伺服器之間提供了雙工非同步通訊功能,也就是說我們可以利用瀏覽器給伺服器傳送訊息,伺服器也可以給瀏 覽器傳送訊息,目前主流瀏覽器的主流版本對WebSocket的支援都算是比較好的,但是在實際開發

SSH 項目中 使用websocket 實現網頁聊天功能

發送 ref asi action 監聽器 remote static scrollto 連接 參考文章 :java使用websocket,並且獲取HttpSession,源碼分析 http://www.cnblogs.com/zhuxiaojie/p/623882

websocket實現簡單聊天程序

spa nodejs end 地址 person focus data 實現 完成 程序的流程圖: 主要代碼: 服務端 app.js 先加載所需要的通信模塊: var express = require(‘express‘); var app = express();

百度t7 課程, websocket 實現簡單聊天

最簡單的聊天室,我寫了一個小時, 寫了10 分鐘,除錯50分鐘 因為 我是小菜鳥,不過凡事都有過程 index.html <!DOCTYPE html> <html lang="en"> <head> <meta c

websocket實現簡單聊天

上個月公司開發APP中用到了實時聊天功能,一開始覺得不可思議,因為完全沒有接觸過,然後聽安卓和ios的說之前的公司都是用第三方sdk的很少看到自己寫聊天功能的(南京大公司不多,我想大點的公司自己寫還是可以的,因為實現功能和商用還是有點區別的),老闆對我們的要求也不高,鼓勵我們

websocket實現實時聊天功能

最近想實現網頁版的仿QQ聊天工具,本來想用ajax實現的,但是一想到要一直輪詢,就感覺有點蠢。後來在網上找到了websocket相關的資料,就拿來跟大家分享下(不是很熟練,現在只實現了群聊,單聊的前端不會寫了。但可以跟大家說說思路)。 伺服器端程式碼: 首先要建

SpringBoot+WebSocket實現線上聊天(一)

線上聊天功能是為了方便HR快速交流,由於HR人數有限,因此這裡並未考慮高併發問題,小夥伴思考問題一定要結合上下文環境。OK,我們先來看看效果圖: 線上聊天效果圖 登陸成功後,點選右上角的鬧鈴圖示,進入到訊息頁面,點選 好友聊天 選項卡,效果如下:

JavaWeb--使用Websocket實現線上聊天功能

package websocket.chat; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSession; import javax.web

基於vue,websocket實現線上聊天功能

    最近專案中一直在使用vue作為前端框架,可是用到的只有很少一部分的功能,特別是vuex,為了更加深入瞭解vue框架,在工作之餘開發了一款基於vue的線上聊天工具,一下是部分功能效果圖1.登入註冊2.新增好友&國際化3.訊息重發歡迎star

springboot+websocket簡單實現,解決websocket failed: Error during WebSocket handshake: Unexpected response

編輯器:idea。tomcat是springboot內建的tomcat,一開始出現 websocket failed: Error during WebSocket handshake: Unexpected response 這個問題的原因是,我一開始在專案中沒有在注入ServerEndp

使用cocoscreator + node.js + websocket實現簡單聊天服務

先上個效果圖: 使用cocoscreator 1.9.1 + node.js + websocket實現,沒有使用socket.io, 全部自己封裝,長連線進行封裝後可以和短連線使用方法一樣,使用簡單,方便以後開發網路遊戲。 1、客戶端:   主要就是聊天內容的顯示,自動換行和背景擴充套件,程式碼大概如下:

***Java中WebSocket實現簡單聊天***

Java中WebSocket實現簡單的聊天 1 在pom.xml中新增Jar包依賴 <dependency> <groupId>org.springframework.boot</groupId> <arti

基於flask框架,使用websocket實現一對一聊天功能

info app lan 提示 function _id 數據 sca 響應 後端代碼: from flask import Flask,request,render_template from geventwebsocket.handler import WebSock

java WebSocket實現簡單聊天室(包括群發和點對點聊天

今天突然看到了WebSocket然後就網上找了一個例子,然後修改了下,實現了簡單的聊天室,包括群聊和點對點聊天。 使用的程式碼如下 jsp程式碼: <%@ page language="java" import="java.util.*" pageEncoding="

【Flask + WebSocket 實現簡單聊天室】

群聊 後端程式碼 from flask import Flask, request, render_template from geventwebsocket.handler import WebSocketHandler from gevent.pywsgi import WS

使用nodejs-websocket 20行程式碼實現簡單聊天

安裝nodejs-websocket: npm install nodejs-websocketindex.html<!DOCTYPE html> <html> <hea

Shell 實現簡單計算器功能

shell 計算器Shell 實現簡單計算器功能,腳本如下:[[email protected]/* */ scripts]# cat jisuan.sh #!/bin/bash print_usage(){ printf $"USAGE:$0 NUM1 {+|-|*|/} NUM2\n"

WPF使用socket實現簡單聊天軟件

title poi utf program ces xaml sender ted static 公司網絡限制不能傳文件,先貼部分代碼 項目結構: 1.解決方案 1.1. Client 1.2. Server Client: <Window

python實現簡單爬蟲功能

我們 目錄 size .com all 本地文件 使用 url alt  在我們日常上網瀏覽網頁的時候,經常會看到一些好看的圖片,我們就希望把這些圖片保存下載,或者用戶用來做桌面壁紙,或者用來做設計的素材。   我們最常規的做法就是通過鼠標右鍵,選擇另存為。但有些圖片鼠標右

在控件內實現簡單畫筆功能

box use from uic eve args class 窗體 down /// <summary> /// 實現窗體內簡單畫筆功能 /// </summary> public class DrawClass {