1. 程式人生 > >spring boot +WebSocket(三) 點對點式

spring boot +WebSocket(三) 點對點式

前兩篇部落格演示了廣播式的websocket 推送。
廣播式有自己的應用場景,但是廣播式不能解決我門一個常見的場景,即訊息由誰傳送、由誰接收的問題。

本例中演示了一個簡單的聊天室程式。例子中只有兩個使用者,互相傳送訊息給彼此,因需要使用者相關內容,所以這裡引入了最簡單的spring Security相關內容。

本文目錄:

後臺

1.新建maven工程

2.新建Websocket 配置類

3.新建WebSecurityConfig配置

4.新建java bean

5.新建WebSocketController類

7.新建對映類WebMvcConfig

8.新建Application 啟動類

前臺

1.匯入指令碼

2.編寫login.html

3.編寫chat.html

效果

後臺

1.新建maven工程

新建maven 工程,pom.xml 檔案內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion> <groupId>com.us.example</groupId> <artifactId>springWebSocket</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId
>
spring-boot-starter-parent</artifactId> <version>1.3.0.RELEASE</version> </parent> <properties> <start-class>com.us.Application</start-class> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> <dependencies> <!-- 核心模組,包括自動配置支援、日誌和YAML --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 測試模組,包括JUnit、Hamcrest、Mockito --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- 引入Web模組 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- SpringWebSocket依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <!-- 引入security模組 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> </project>

2.新建WebsocketConfig 配置類

package com.us.example.config;

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;

/**
 * Created by yangyibo on 16/12/29.
 */
@Configuration
@EnableWebSocketMessageBroker
//通過EnableWebSocketMessageBroker 開啟使用STOMP協議來傳輸基於代理(message broker)的訊息,此時瀏覽器支援使用@MessageMapping 就像支援@RequestMapping一樣。
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) { //endPoint 註冊協議節點,並對映指定的URl

        //註冊一個名字為"endpointChat" 的endpoint,並指定 SockJS協議。   點對點-用
        registry.addEndpoint("/endpointChat").withSockJS();
    }


    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {//配置訊息代理(message broker)
        //點對點式增加一個/queue 訊息代理
        registry.enableSimpleBroker("/queue","/topic");

    }
}

3.新建WebSecurityConfig配置

package com.us.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/login").permitAll()//根路徑和/login路徑不攔截
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login") //2登陸頁面路徑為/login
                .defaultSuccessUrl("/chat") //3登陸成功轉向chat頁面
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }

    //4在記憶體中配置兩個使用者 wyf 和 wisely ,密碼和使用者名稱一致,角色是 USER
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .inMemoryAuthentication()
                .withUser("wyf").password("wyf").roles("USER")
                .and()
                .withUser("wisely").password("wisely").roles("USER");
    }
    //5忽略靜態資源的攔截
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/static/**");
    }

}

4.新建java bean

package com.us.example.bean;

/**
 * Created by yangyibo on 16/12/29.
 */
public class Message {
    private String name;

    public String getName(){
        return name;
    }
}

5.新建WebSocketController類

package com.us.example.controller;

import com.us.example.bean.Message;
import com.us.example.bean.Response;
import com.us.example.service.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.security.Principal;

/**
 * Created by yangyibo on 16/12/29.
 *
 */
@Controller
public class WebSocketController {
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @MessageMapping("/chat")
    //在springmvc 中可以直接獲得principal,principal 中包含當前使用者的資訊
    public void handleChat(Principal principal, Message message) {

        /**
         * 此處是一段硬編碼。如果傳送人是wyf 則傳送給 wisely 如果傳送人是wisely 就傳送給 wyf。
         */
        if (principal.getName().equals("wyf")) {
            //通過convertAndSendToUser 向用戶傳送資訊,
            // 第一個引數是接收訊息的使用者,第二個引數是瀏覽器訂閱的地址,第三個引數是訊息本身

            messagingTemplate.convertAndSendToUser("wisely",
                    "/queue/notifications", principal.getName() + "-send:"
                            + message.getName());
        } else {
            messagingTemplate.convertAndSendToUser("wyf",
                    "/queue/notifications", principal.getName() + "-send:"
                            + message.getName());
        }
    }
}

7.新建對映類WebMvcConfig

為HTML 提供便捷的路徑對映。

package com.us.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebMvcConfig  extends WebMvcConfigurerAdapter{
     @Override
       public void addViewControllers(ViewControllerRegistry registry) {
           registry.addViewController("/login").setViewName("/login");
           registry.addViewController("/chat").setViewName("/chat");
       }

}

8.新建Application 啟動類

package com.us.example;

/**
 * Created by yangyibo on 16/12/29.
 */
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;

import static org.springframework.boot.SpringApplication.run;

@ComponentScan(basePackages ="com.us.example")
@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = run(Application.class, args);
    }
}

前臺

1.匯入指令碼

新增指令碼,將stomp.js、sockjs.min.js 以及jQuery 指令碼放在src/main/resources/static下。

2.編寫login.html

在src/main/resources/templates 下新建 login.html。(原始碼會在文章底部給出)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<meta charset="UTF-8" />
<head>
    <title>登陸頁面</title>
</head>
<body>
<div th:if="${param.error}">
    無效的賬號和密碼
</div>
<div th:if="${param.logout}">
    你已登出
</div>
<form th:action="@{/login}" method="post">
    <div><label> 賬號 : <input type="text" name="username"/> </label></div>
    <div><label> 密碼: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="登陸"/></div>
</form>
</body>
</html>

3.編寫chat.html

在src/main/resources/templates 下新建 chat.html。(原始碼會在文章底部給出)
<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8" />
<head>
    <title>Home</title>
    <script th:src="@{sockjs.min.js}"></script>
    <script th:src="@{stomp.min.js}"></script>
    <script th:src="@{jquery.js}"></script>
</head>
<body>
<p>
    聊天室
</p>

<form id="wiselyForm">
    <textarea rows="4" cols="60" name="text"></textarea>
    <input type="submit"/>
</form>

<script th:inline="javascript">
    $('#wiselyForm').submit(function(e){
        e.preventDefault();
        var text = $('#wiselyForm').find('textarea[name="text"]').val();
        sendSpittle(text);
    });
    //連結endpoint名稱為 "/endpointChat" 的endpoint。
    var sock = new SockJS("/endpointChat");
    var stomp = Stomp.over(sock);
    stomp.connect('guest', 'guest', function(frame) {

        /**
 訂閱了/user/queue/notifications 傳送的訊息,這裡雨在控制器的 convertAndSendToUser 定義的地址保持一致,

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

         *  */
        stomp.subscribe("/user/queue/notifications", handleNotification);
    });



    function handleNotification(message) {
        $('#output').append("<b>Received: " + message.body + "</b><br/>")
    }

    function sendSpittle(text) {
        stomp.send("/chat", {}, JSON.stringify({ 'name': text }));//3
    }
    $('#stop').click(function() {sock.close()});
</script>

<div id="output"></div>
</body>
</html>

效果

登入成功後就可以相互發送資訊聊天了。

這裡寫圖片描述
這裡寫圖片描述

本文參考:《JavaEE開發的顛覆者:Spring Boot實戰 》

相關推薦

spring boot WebSocket

前兩篇部落格演示了廣播式的websocket 推送。 廣播式有自己的應用場景,但是廣播式不能解決我門一個常見的場景,即訊息由誰傳送、由誰接收的問題。 本例中演示了一個簡單的聊天室程式。例子中只有兩個使用者,互相傳送訊息給彼此,因需要使用者相關內容,所以這裡引

Spring Boot實戰筆記-- Spring常用配置Bean的初始化和銷毀、Profile

div nbsp troy string 實例化 public ive work 初始 一、Bean的初始化和銷毀   在我們的實際開發的時候,經常會遇到Bean在使用之前或之後做些必要的操作,Spring對Bean的生命周期操作提供了支持。在使用Java配置和註解配置下提

Spring Boot參考教程內部應用監控Actuator

使用方式 實現類 pat igp pid localhost aid 倉庫 默認 3. 內部應用監控(Actuator) 如上2.4中所述,傳統spring工程中工程的初始化過程,bean的生命周期,應用的內部健康情況均無法監控,為了解決這個問題,spring boot提供

spring boot入門筆記 - banner、熱部署、命令行參數

nal rop dep ioc devtools 一點 一個 splay option   1、一般項目啟動的時候,剛開始都有一個《spring》的標誌,如何修改呢?在resources下面添加一個banner.txt就行了,springboot會自動給你加載banner.

Spring Boot學習筆記—— 新增Mybatis、Druid

一、前言 之前我們對Spring Boot的View和Control配置都有了一定的瞭解,在Model層配置上,我們將使用Mybatis、Druid進行開發,下面就對其進行配置。 二、開始配置 MyBatis 是一款優秀的持久層框架,Druid是一個高效能的資料庫連線池,並且提供

spring boot 整合 jpa -- 之表關係對映

spring boot 整合 jpa (一) – 之基礎配置 https://blog.csdn.net/qq_41463655/article/details/82939481 spring boot 整合 jpa (二) – 之資料操作 https://blog.csdn.net/q

Spring Boot 最佳實踐模板引擎FreeMarker整合

一、FreeMaker介紹 FreeMarker是一款免費的Java模板引擎,是一種基於模板和資料生成文字(HMLT、電子郵件、配置檔案、原始碼等)的工具,它不是面向終端使用者的,而是一款程式設計師使用的元件。 FreeMarker最初設計是用來在MVC模式的Web

Spring boot使用總結校驗[email protected] 使用

spring boot 1.4預設使用 hibernate validator 5.2.4 Final實現校驗功能。hibernate validator 5.2.4 Final是JSR 349 Bean Validation 1.1的具體實現。 一 初步使用

Spring boot整合websocket----傳統註冊方式

修改配置類 @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer{ @Override public void regist

Spring Boot學習筆記檔案上傳與訪問靜態檔案

檔案上傳 寫法和Spring MVC沒啥區別看起來 package org.test.Controll; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.we

Spring Boot學習筆記——使用JPA查詢資料庫返回需要的資料

1.概述 在上一篇中,我們已經學會了如何建立執行一個Spring Boot程式,但是他還遠遠滿足不了一個網站的基本需求,完成這篇的學習後我們就能實現一個簡單的雛形。 2.目標 在本篇中,實現的簡單的資料庫訪問,讀取資料的功能。 3.詳細步驟 (1)在第

CentOS 7 spring boot專案上線

  域名註冊 百度阿里雲 搜尋框搜素 域名  com 或 cn選一個進去   點選加入清單下方會提示選擇 :需要實名認證才能購買         

Spring Boot 學習筆記Spring boot 中的SSM

Spring boot 下的 Spring mvc @Controller:即為Spring mvc的註解,處理http請求; @RestController:Spring4後新增註解,是@Controller與@ResponseBody的組合註解,用於返回字串或json資料; package c

spring boot基礎搭建

重新配置hibernate: 在config包下建立HibernateConfiguration類如下: 程式碼: package com.config; im

Spring boot Caffeine快取——使用註解

註解在Spring中的應用很廣泛,幾乎成為了其標誌,這裡說下使用註解來整合快取。 cache方面的註解主要有以下5個 @Cacheable 觸發快取入口(這裡一般放在建立和獲取的方法上) @CacheEvict 觸發快取的eviction(用於刪除的

Spring Boot學習之Spring Boot的核心

1、Spring Boot的專案一般都會有*Application的入口類,入口類中會有main方法,這是一個標準的Java應用程式的入口方法。 @SpringBootApplication註解是Spring Boot的核心註解,它其實是一個組合註解:下面我們

Spring Boot常用註解

一.概述 Spring Boot推薦使用java配置完全代替XML配置,java配置是通過@Configration和@Bean註解實現的 @Configration註解聲明當前類是一個配置類,相當於Spring中的一個XML檔案 @Bean註解作用在方法

spring boot WebSocket 廣播

WebSocket 為瀏覽器和伺服器端提供了雙工非同步通訊的功能,即瀏覽器可以向伺服器傳送訊息,伺服器也可以向瀏覽器傳送訊息。WebSocket 需要瀏覽器的支援,如IE 10+、Chrome 13+、Firefox 6+。 Websocket 是通過一個so

spring boot學習系列

web服務器 應用程序 spring 控制器 做什麽 spring boot開發第一個應用程序1、spring boot是什麽?2、spring boot容易上手嗎?寫這篇文章技術文章,主要是記錄日常的學習以及理解。我們重新認識一下spring假設你受命使用spring開發一個簡單的hel

Spring學習之路bean註解管理AOP操作

spec resource 自定義屬性 開始 java framework XML 方法名 jar包 在類上面、方法上面、屬性上面添加註解;並用bean來管理; 書寫方法:@註解名稱(屬性名稱=值) 第一步:導入jar包   導入spring-aop.jar(spri