万事第一步:导包

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-websocket</artifactId>
    4. </dependency>

    第二步:把你写配置文件类

    1. package com.feri.chat.config;
    2. import org.springframework.context.annotation.Bean;
    3. import org.springframework.context.annotation.Configuration;
    4. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    5. /**
    6. * WebSocket的配置类
    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. @Configuration
    41. public class WebSocketConfig {
    42. @Bean
    43. public ServerEndpointExporter createSEE(){
    44. return new ServerEndpointExporter();
    45. }
    46. }

    第三步:实现服务类

    1. package com.feri.chat.chat;
    2. import org.springframework.context.annotation.Scope;
    3. import org.springframework.stereotype.Component;
    4. import javax.websocket.*;
    5. import javax.websocket.server.PathParam;
    6. import javax.websocket.server.ServerEndpoint;
    7. import java.io.IOException;
    8. import java.util.concurrent.ConcurrentHashMap;
    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. @Component
    42. @Scope(scopeName = "prototype")
    43. @ServerEndpoint("/chat/server/{nickname}")
    44. public class ChatServer {
    45. private String nickname;//用户的昵称
    46. private Session session;//会话对象
    47. public static ConcurrentHashMap<String,Session> users=new ConcurrentHashMap<>();//记录当前用户
    48. @OnOpen //连接-服务端
    49. public void open(@PathParam("nickname") String name,Session session){
    50. if(users.contains(name)){
    51. //昵称已占用
    52. sendMsg(session,"亲,昵称已被占用!");
    53. }else {
    54. this.nickname=name;
    55. this.session=session;
    56. users.put(name,session);
    57. sendMoreMsg("欢迎 "+name+" 进入聊天区!");
    58. }
    59. }
    60. @OnMessage //监听 消息,接收消息
    61. public void message(String msg,Session session){
    62. System.err.println("服务端接收:"+msg);
    63. sendMsg(session,"已收到,时间-"+System.currentTimeMillis());
    64. sendMoreMsg(nickname+"-说:"+msg);
    65. }
    66. @OnError //异常监听,只要出错误
    67. public void error(Throwable throwable){
    68. System.err.println("出错了");
    69. }
    70. @OnClose //监听关闭
    71. public void close(Session session){
    72. users.remove(nickname);//移除
    73. sendMoreMsg("让我们掌声欢送 "+nickname+" 的离开!");
    74. }
    75. //发送单挑消息
    76. private void sendMsg(Session session,String msg){
    77. try {
    78. //发送消息
    79. session.getBasicRemote().sendText(msg);
    80. } catch (IOException e) {
    81. e.printStackTrace();
    82. }
    83. }
    84. //群发消息
    85. private static void sendMoreMsg(String msg){
    86. try {
    87. //发送消息
    88. for(String s:users.keySet()){
    89. users.get(s).getBasicRemote().sendText(msg);
    90. }
    91. } catch (IOException e) {
    92. e.printStackTrace();
    93. }
    94. }
    95. //推送消息
    96. public static boolean pushMsg(String msg){
    97. sendMoreMsg(msg);
    98. return true;
    99. }
    100. }

    第四步:测试(http://www.jsons.cn/websocket/)
    image.png
    前段参考代码:

    1. <template>
    2. <div>
    3. <!-- 1.连接 -->
    4. <div>
    5. <van-cell-group inset>
    6. <van-field
    7. v-model="nickname"
    8. center
    9. label-width="50px"
    10. clearable
    11. label="昵称"
    12. placeholder="请输入昵称"
    13. >
    14. <template #button>
    15. <van-button size="small" type="primary" @click="joinRoom()">连接</van-button>
    16. <van-button size="small" style="margin-left: 10px;" type="info" @click="exitRoom()">退出</van-button>
    17. </template>
    18. </van-field>
    19. </van-cell-group>
    20. </div>
    21. <!-- 2.聊天信息 -->
    22. <div>
    23. <van-cell v-for="item in msgs" :key="item" :title="item" />
    24. </div>
    25. <!-- 3.发送消息 -->
    26. <div style="position: absolute; bottom: 37px;width: 100%;">
    27. <van-cell-group inset>
    28. <van-field
    29. v-model="msg"
    30. center
    31. clearable
    32. placeholder="请输入聊天信息"
    33. >
    34. <template #button>
    35. <van-button size="small" type="primary" @click="sendMsg()">发送</van-button>
    36. </template>
    37. </van-field>
    38. </van-cell-group>
    39. </div>
    40. </div>
    41. </template>
    42. <script>
    43. export default{
    44. data(){
    45. return{
    46. nickname:"",
    47. msg:"",
    48. msgs:[
    49. "测试01"
    50. ],
    51. ws:{}
    52. }
    53. },
    54. methods:{
    55. joinRoom(){
    56. if ('WebSocket' in window){
    57. //完成实例化
    58. this.ws = new WebSocket("ws://localhost:9999/chat/server/"+this.nickname);
    59. //监听消息接收
    60. this.ws.onmessage = (res=>{
    61. console.log("数据已接收...",res.data);
    62. this.msgs.push(res.data);
    63. });
    64. //连接服务器
    65. this.ws.onopen=(res=>{
    66. this.msgs.push("加入成功");
    67. });
    68. }
    69. },
    70. exitRoom(){
    71. console.log("退出");
    72. this.ws.close();
    73. this.msgs.push("退出聊天室");
    74. this.nickname="";
    75. },
    76. sendMsg(){//发送聊天消息
    77. this.ws.send(this.msg);//发送消息
    78. this.msgs.push("我说:"+this.msg);
    79. this.msg="";
    80. }
    81. }
    82. }
    83. </script>
    84. <style>
    85. </style>