2.什么是websocket?
websocket是一种在单个TCP连接上进行全双工通信的协议,以被W3C定为标准
3.SpringBoot整合WebSocket
1.消息群发
1.1:创建项目引入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>websocket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>websocket</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<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-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.2配置websocket
package com.example.websocket.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker //开启WebSocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//设置消息代理的前缀,即如果消息的前缀是"/topic",就会将消息转发给消息代理(broker),
//再由消息代理将消息广播给当前连接的客户端
registry.enableSimpleBroker("/topic");
//配置一个或多个前缀,通过这些前缀过滤出需要被注解方法处理的消息,例如,
//前缀为"/app"的destination可以通过@MessageMapping注解方法处理,而其他destination
//(例如"/topic" "/queue")将直接交给broker处理
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//定义一个前缀为"/chat"的endPoint,并开启sockjs支持,sockjs可以解决浏览器
//对WebSocket的兼容性问题,客户端通过这里配置的URL来建立WebSocket连接
registry.addEndpoint("/chat").withSockJS();
}
}
1.3定义controller
package com.example.websocket.controller;
import com.example.websocket.entity.Message;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class GreetingController {
/**
* @MessageMapping("/hello")注解方法将用来接收"/app/hello"路径发送来的消息
* 在注解方法中对消息进行处理后,在将消息转发到 @SendTo定义的路径上,而@SendTo路径是一个前缀为 /topic
* 的路径,因此该消息将被交给消息代理broker,再由broker进行广播
* @param message
* @return
* @throws Exception
*/
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Message greeting(Message message) throws Exception{
return message;
}
}
1.4构建聊天页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>群聊</title>
<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>
<div>
<label for="name">请输入姓名:</label>
<input type="text" id="name" placeholder="用户名">
</div>
<div>
<button id="connect" type="button">连接</button>
<button id="disconnect" type="button" disabled="disabled">断开连接</button>
</div>
<div id="chat" style="display: none"></div>
<div>
<label for="name">请输入聊天内容:</label>
<input type="text" id="content" placeholder="聊天内容">
</div>
<button id="send" type="button">发送</button>
<div id="greetings"></div>
<div id="conversation" style="display: none">群聊进行中</div>
</body>
</html>
app.js是自定义的
var stompClient = null;
/**
* 设置连接
* @param connected
*/
function setConnect(connected) {
$("#connect").prop("disabled",connected);
$("#disconnect").prop("disabled",!connected);
if(connected){
$("#conversation").show();
$("#chat").show();
}else{
$("#conversation").hide();
$("#chat").hide();
}
$("#greetings").html("");
}
/**
* 建立一个WebSocket连接,在建立WebSocket连接时,用户必须先输入用户名,然后在建立连接
*/
function connect() {
if(!$("#name").val()){
return;
}
var socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect({},function (frame) {
setConnect(true);
stompClient.subscribe('/topic/greetings',function (greeting) {
showGreeting(JSON.parse(greeting.body));
})
})
}
/**
* 断开连接
*/
function disconnect() {
if(stompClient !== null){
stompClient.disconnect();
}
setConnect(false);
}
/**
* 发送名字
*/
function sendName() {
stompClient.send('/app/hello',{},JSON.stringify({'name':$("#name").val(),'content':$("#content").val()}));
}
/**
* 显示聊天内容
* @param message
*/
function showGreeting(message) {
$("#greetings").append("<div>"+message.name+":"+message.content+"</div>")
}
/**
* 页面加载
*/
$(function () {
$("#connect").click(function () {
connect();
});
$("#disconnect").click(function () {
disconnect();
});
$("#send").click(function () {
sendName();
});
})
消息点对点发送
1.添加依赖,这里有用户的概念所以添加security安全管理依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>websocket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>websocket</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<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-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.配置spring security
package com.example.websocket.config;
import org.springframework.context.annotation.Bean;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
/**
* $2a$10$J3/OJtLW1vWyrdR4xn0/Beibr8hq.V6fAjEIdeJawknnRe0TUgF.a
* $2a$10$3DcvpVwQ41zjPXF5te2wCe8TseYVJtJCT0HmlsTGH4/DBUDctG8Ym
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password("$2a$10$J3/OJtLW1vWyrdR4xn0/Beibr8hq.V6fAjEIdeJawknnRe0TUgF.a")
.roles("admin")
.and()
.withUser("sang")
.password("$2a$10$3DcvpVwQ41zjPXF5te2wCe8TseYVJtJCT0HmlsTGH4/DBUDctG8Ym")
.roles("user");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
密码加密方式
@RunWith(SpringRunner.class)
@SpringBootTest
public class WebsocketApplicationTests {
@Test
public void contextLoads() {
}
public static void main(String[] args) {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode("123");
String encode2 = bCryptPasswordEncoder.encode("123");
System.out.println(encode);
System.out.println(encode2);
}
}
结果
"C:\Program Files\Java\jdk1.8.0_112\bin\java.exe" "-javaagent:D:\idea\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=49166:D:\idea\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_112\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\rt.jar;F:\gitsource\guns\stylefeng-guns-master\comprehensive\websocket\target\test-classes;F:\gitsource\guns\stylefeng-guns-master\comprehensive\websocket\target\classes;D:\m2_repository\org\springframework\boot\spring-boot-starter\2.1.9.RELEASE\spring-boot-starter-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot\2.1.9.RELEASE\spring-boot-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\spring-context\5.1.10.RELEASE\spring-context-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-autoconfigure\2.1.9.RELEASE\spring-boot-autoconfigure-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-logging\2.1.9.RELEASE\spring-boot-starter-logging-2.1.9.RELEASE.jar;D:\m2_repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\m2_repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\m2_repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;D:\m2_repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;D:\m2_repository\org\slf4j\jul-to-slf4j\1.7.28\jul-to-slf4j-1.7.28.jar;D:\m2_repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;D:\m2_repository\org\springframework\spring-core\5.1.10.RELEASE\spring-core-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-jcl\5.1.10.RELEASE\spring-jcl-5.1.10.RELEASE.jar;D:\m2_repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-test\2.1.9.RELEASE\spring-boot-starter-test-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-test\2.1.9.RELEASE\spring-boot-test-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-test-autoconfigure\2.1.9.RELEASE\spring-boot-test-autoconfigure-2.1.9.RELEASE.jar;D:\m2_repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;D:\m2_repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;D:\m2_repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;D:\m2_repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;D:\m2_repository\junit\junit\4.12\junit-4.12.jar;D:\m2_repository\org\assertj\assertj-core\3.11.1\assertj-core-3.11.1.jar;D:\m2_repository\org\mockito\mockito-core\2.23.4\mockito-core-2.23.4.jar;D:\m2_repository\net\bytebuddy\byte-buddy\1.9.16\byte-buddy-1.9.16.jar;D:\m2_repository\net\bytebuddy\byte-buddy-agent\1.9.16\byte-buddy-agent-1.9.16.jar;D:\m2_repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;D:\m2_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\m2_repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;D:\m2_repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;D:\m2_repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;D:\m2_repository\org\springframework\spring-test\5.1.10.RELEASE\spring-test-5.1.10.RELEASE.jar;D:\m2_repository\org\xmlunit\xmlunit-core\2.6.3\xmlunit-core-2.6.3.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-websocket\2.1.9.RELEASE\spring-boot-starter-websocket-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-web\2.1.9.RELEASE\spring-boot-starter-web-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-json\2.1.9.RELEASE\spring-boot-starter-json-2.1.9.RELEASE.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-databind\2.9.9.3\jackson-databind-2.9.9.3.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\m2_repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.9\jackson-datatype-jdk8-2.9.9.jar;D:\m2_repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.9\jackson-datatype-jsr310-2.9.9.jar;D:\m2_repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.9\jackson-module-parameter-names-2.9.9.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-tomcat\2.1.9.RELEASE\spring-boot-starter-tomcat-2.1.9.RELEASE.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.26\tomcat-embed-core-9.0.26.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.26\tomcat-embed-el-9.0.26.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.26\tomcat-embed-websocket-9.0.26.jar;D:\m2_repository\org\hibernate\validator\hibernate-validator\6.0.17.Final\hibernate-validator-6.0.17.Final.jar;D:\m2_repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;D:\m2_repository\org\jboss\logging\jboss-logging\3.3.3.Final\jboss-logging-3.3.3.Final.jar;D:\m2_repository\com\fasterxml\classmate\1.4.0\classmate-1.4.0.jar;D:\m2_repository\org\springframework\spring-web\5.1.10.RELEASE\spring-web-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-webmvc\5.1.10.RELEASE\spring-webmvc-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-messaging\5.1.10.RELEASE\spring-messaging-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-beans\5.1.10.RELEASE\spring-beans-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-websocket\5.1.10.RELEASE\spring-websocket-5.1.10.RELEASE.jar;D:\m2_repository\org\webjars\webjars-locator-core\0.35\webjars-locator-core-0.35.jar;D:\m2_repository\org\slf4j\slf4j-api\1.7.28\slf4j-api-1.7.28.jar;D:\m2_repository\org\apache\commons\commons-lang3\3.8.1\commons-lang3-3.8.1.jar;D:\m2_repository\org\apache\commons\commons-compress\1.9\commons-compress-1.9.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-core\2.9.9\jackson-core-2.9.9.jar;D:\m2_repository\org\webjars\sockjs-client\1.1.2\sockjs-client-1.1.2.jar;D:\m2_repository\org\webjars\stomp-websocket\2.3.3\stomp-websocket-2.3.3.jar;D:\m2_repository\org\webjars\jquery\3.3.1\jquery-3.3.1.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-security\2.1.9.RELEASE\spring-boot-starter-security-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\spring-aop\5.1.10.RELEASE\spring-aop-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\security\spring-security-config\5.1.6.RELEASE\spring-security-config-5.1.6.RELEASE.jar;D:\m2_repository\org\springframework\security\spring-security-core\5.1.6.RELEASE\spring-security-core-5.1.6.RELEASE.jar;D:\m2_repository\org\springframework\security\spring-security-web\5.1.6.RELEASE\spring-security-web-5.1.6.RELEASE.jar;D:\m2_repository\org\springframework\spring-expression\5.1.10.RELEASE\spring-expression-5.1.10.RELEASE.jar" com.example.websocket.WebsocketApplicationTests
$2a$10$J3/OJtLW1vWyrdR4xn0/Beibr8hq.V6fAjEIdeJawknnRe0TUgF.a
$2a$10$3DcvpVwQ41zjPXF5te2wCe8TseYVJtJCT0HmlsTGH4/DBUDctG8Ym
Process finished with exit code 0
改造websocket
package com.example.websocket.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker //开启WebSocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//设置消息代理的前缀,即如果消息的前缀是"/topic",就会将消息转发给消息代理(broker),
//再由消息代理将消息广播给当前连接的客户端
registry.enableSimpleBroker("/topic","/queue");
//配置一个或多个前缀,通过这些前缀过滤出需要被注解方法处理的消息,例如,
//前缀为"/app"的destination可以通过@MessageMapping注解方法处理,而其他destination
//(例如"/topic" "/queue")将直接交给broker处理
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//定义一个前缀为"/chat"的endPoint,并开启sockjs支持,sockjs可以解决浏览器
//对WebSocket的兼容性问题,客户端通过这里配置的URL来建立WebSocket连接
registry.addEndpoint("/chat").withSockJS();
}
}
配置controller
package com.example.websocket.controller;
import com.example.websocket.entity.Chat;
import com.example.websocket.entity.Message;
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 java.security.Principal;
/**
* 群发消息依然使用@SendTo注解来实现,点对点的消息发送则使用SimpMessagingTemplate来实现
*/
@Controller
public class GreetingController2 {
@Autowired
SimpMessagingTemplate messagingTemplate;
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Message greeting(Message message)throws Exception{
return message;
}
/**
* 定义了一个新的消息处理接口, @MessageMapping("/chat")注解表示来自"/app/chat"路径的消息将被
* chat方法处理。chat方法的第一个参数Principal可以用来获取当前用户登录用户的信息,
* 第二个参数则是客户端发送来的消息。
* 在chat方法中,首先获取当前用户的用户名,设置给chat对象的from属性,再将消息发送出去,发送的目标用户
* 就是chat对象的to属性值。
* to属性表示消息的目标用户
* from表示消息从哪里来
* content则是消息主题的内容
* @param principal
* @param chat
*/
@MessageMapping("/chat")
public void chat(Principal principal, Chat chat){
String from = principal.getName();
chat.setFrom(from);
messagingTemplate.convertAndSendToUser(chat.getTo(),"/queue/chat",chat);
}
}
创建在线聊天页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单聊</title>
<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="chat.js"></script>
</head>
<body>
<div id="chat">
<div id="chatsContent"></div>
</div>
<div>
请输入聊天内容:
<input type="text" id="content" placeholder="聊天内容">
目标用户:
<input type="text" id="to" placeholder="目标用户">
<button id="send" type="button">发送</button>
</div>
</body>
</html>
chat.,js
var stompClient = null;
function connect() {
var socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect({},function (frame) {
stompClient.subscribe('/user/queue/chat',function (chat) {
showGreeting(JSON.parse(chat.body));
});
});
}
function sendMsg() {
stompClient.send("/app/chat",{},JSON.stringify({'content': $("#content").val(),'to':$("#to").val()}));
}
function showGreeting(message) {
$("#chatsContent").append("<div>"+message.from+":"+message.content+"</div>");
}
$(function () {
connect();
$("#send").click(function () {
sendMsg();
});
})