好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SpringBoot的WebSocket实现单聊群聊

本文实例为大家分享了SpringBoot的WebSocket实现单聊群聊,供大家参考,具体内容如下

说在开头

在HTTP协议中,所有的请求都是由客户端发送给服务端,然后服务端发送请求
要实现服务器向客户端推送消息有几种methods:

1、轮询

大量无效请求,浪费资源

2、长轮询

有新数据再推送,但这会导致连接超时,有一定隐患

3、Applet和Flash

过时,安全隐患,兼容性不好

消息群发

创建新项目:

添加依赖:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

< dependency >

   < groupId >org.springframework.boot</ groupId >

   < artifactId >spring-boot-starter-web</ artifactId >

  </ dependency >

  < dependency >

   < groupId >org.springframework.boot</ groupId >

   < artifactId >spring-boot-starter-websocket</ artifactId >

  </ dependency >

  < dependency >

   < groupId >org.webjars</ groupId >

   < artifactId >sockjs-client</ artifactId >

   < version >1.1.2</ version >

  </ dependency >

  < dependency >

   < groupId >org.webjars</ groupId >

   < artifactId >jquery</ artifactId >

   < version >3.3.1</ version >

  </ dependency >

  < dependency >

   < groupId >org.webjars</ groupId >

   < artifactId >stomp-websocket</ artifactId >

   < version >2.3.3</ version >

  </ dependency >

  < dependency >

   < groupId >org.webjars</ groupId >

   < artifactId >webjars-locator-core</ artifactId >

</ dependency >

创建WebSocket配置类:WebSocketConfig

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

@Configuration

@EnableWebSocketMessageBroker //注解开启webSocket消息代理

public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

  /**

  * 配置webSocket代理类

  * @param registry

  */

  @Override

  public void configureMessageBroker(MessageBrokerRegistry registry) {

  registry.enableSimpleBroker( "/topic" ); //代理消息的前缀

  registry.setApplicationDestinationPrefixes( "/app" );  //处理消息的方法前缀

  }

  @Override

  public void registerStompEndpoints(StompEndpointRegistry registry) {

  registry.addEndpoint( "/chat" ).withSockJS();  //定义一个/chat前缀的endpioint,用来连接

  }

}

创建Bean

?

1

2

3

4

5

6

7

8

/**

  * 群消息类

  */

public class Message {

  private String name;

  private String content;

//省略getter& setter

}

定义controller的方法:

?

1

2

3

4

5

6

7

8

9

10

11

12

/**

  * MessageMapping接受前端发来的信息

  * SendTo 发送给信息WebSocket消息代理,进行广播

  * @param message 页面发来的json数据封装成自定义Bean

  * @return 返回的数据交给WebSocket进行广播

  * @throws Exception

  */

  @MessageMapping ( "/hello" )

  @SendTo ( "/topic/greetings" )

  public Message greeting(Message message) throws Exception {

  return message;

  }

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

< html lang = "en" >

< head >

  < meta charset = "UTF-8" >

  < title >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 >

  var stompClient = null;

  //点击连接以后的页面改变

  function setConnected(connection) {

   $("#connect").prop("disable",connection);

   $("#disconnect").prop("disable",!connection);

   if (connection) {

   $("#conversation").show();

   $("#chat").show();

 

   } else {

   $("#conversation").hide();

   $("#chat").hide();

   }

   $("#greetings").html("");

  }

  //点击连接按钮建立连接

  function connect() {

   //如果用户名为空直接跳出

   if (!$("#name").val()) {

   return;

   }

   //创建SockJs实例,建立连接

   var sockJS = new SockJS("/chat");

   //创建stomp实例进行发送连接

   stompClient = Stomp.over(sockJS);

   stompClient.connect({}, function (frame) {

   setConnected(true);

   //订阅服务端发来的信息

   stompClient.subscribe("/topic/greetings", function (greeting) {

    //将消息转化为json格式,调用方法展示

    showGreeting(JSON.parse(greeting.body));

   });

   });

  }

  //断开连接

  function disconnect() {

   if (stompClient !== null) {

   stompClient.disconnect();

   }

   setConnected(false);

  }

  //发送信息

  function sendName() {

   stompClient.send("/app/hello",{},JSON.stringify({'name': $("#name").val() , 'content': $("#content").val()}));

  }

  //展示聊天房间

  function showGreeting(message) {

   $("#greetings").append("< div >"+message.name + ":" + message.content + "</ div >");

  }

  $(function () {

   $("#connect").click(function () {

   connect();

   });

   $("#disconnect").click(function () {

   disconnect();

   });

   $("#send").click(function () {

   sendName();

   })

  })

  </ 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" >断开连接</ button >

</ div >

< div id = "chat" style = "display: none;" >

  < div >

  < label for = "name" ></ label >

  < input type = "text" id = "content" placeholder = "聊天内容" >

  </ div >

  < button id = "send" type = "button" >发送</ button >

  < div id = "greetings" >

  < div id = "conversation" style = "display: none;" >群聊进行中</ div >

  </ div >

</ div >

</ body >

</ html >

私聊

既然是私聊,就要有对象目标,也是用户,可以用SpringSecurity引入
所以添加额外依赖:

?

1

2

3

4

< dependency >

  < groupId >org.springframework.boot</ groupId >

  < artifactId >spring-boot-starter-security</ artifactId >

</ dependency >

配置SpringSecurity

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@Configuration

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Bean

  PasswordEncoder passwordEncoder(){

  return new BCryptPasswordEncoder();

  }

  @Override

  protected void configure(AuthenticationManagerBuilder auth) throws Exception {

  auth.inMemoryAuthentication()

   .withUser( "panlijie" ).roles( "admin" ).password( "$2a$10$5Pf0KhCdnrpMxP5aRrHvMOsvV2fvfWJqk0SEDa9vQ8OWwV8emLFhi" )

   .and()

   .withUser( "suyanxia" ).roles( "user" ).password( "$2a$10$5Pf0KhCdnrpMxP5aRrHvMOsvV2fvfWJqk0SEDa9vQ8OWwV8emLFhi" );

  }

  @Override

  protected void configure(HttpSecurity http) throws Exception {

  http.authorizeRequests()

   .anyRequest().authenticated()

   .and()

   .formLogin()

   .permitAll();

  }

}

在原来的WebSocketConfig配置类中修改:也就是多了一个代理消息前缀:"/queue"

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

@Configuration

@EnableWebSocketMessageBroker //注解开启webSocket消息代理

public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

  /**

  * 配置webSocket代理类

  * @param registry

  */

  @Override

  public void configureMessageBroker(MessageBrokerRegistry registry) {

  registry.enableSimpleBroker( "/topic" , "/queue" ); //代理消息的前缀

  registry.setApplicationDestinationPrefixes( "/app" );  //处理消息的方法前缀

  }

  @Override

  public void registerStompEndpoints(StompEndpointRegistry registry) {

  registry.addEndpoint( "/chat" ).withSockJS();  //定义一个/chat前缀的endpioint,用来连接

  }

}

创建Bean:

?

1

2

3

4

5

6

public class Chat {

  private String to;

  private String from;

  private String content;

//省略getter& setter

}

添加controller方法:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

/**

* 点对点发送信息

* @param principal 当前用户的信息

* @param chat 发送的信息

*/

@MessageMapping ( "chat" )

public void chat(Principal principal, Chat chat) {

//获取当前对象设置为信息源

String from = principal.getName();

chat.setFrom(from);

//调用convertAndSendToUser("用户名","路径","内容");

simpMessagingTemplate.convertAndSendToUser(chat.getTo(), "/queue/chat" , chat);

}

创建页面:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

< html lang = "en" >

< head >

  < meta charset = "UTF-8" >

  < title >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 >

  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();

   });

  });

  </ script >

</ head >

< body >

< div id = "chat" >

  < div id = "chatsContent" >

  </ div >

  < div >

  请输入聊天内容

  < input type = "text" id = "content" placeholder = "聊天内容" >

  < input type = "text" id = "to" placeholder = "目标用户" >

  < button type = "button" id = "send" >发送</ button >

  </ div >

</ div >

</ body >

</ html >

暂结!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/coding_deliver/article/details/109568091

查看更多关于SpringBoot的WebSocket实现单聊群聊的详细内容...

  阅读:21次