通过websocket,springboot,vue实现简单在线聊天室(运用了ngrok)

依赖

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

后端

package com.wh.websockettest.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @author:wanghao
 */
@Configuration
public class WebSocketStompConfig {
    //这个bean的注册,用于扫描带有@ServerEndpoint的注解成为websocket  ,如果你使用外置的tomcat就不需要该配置文件
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

package com.wh.websockettest.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author:wanghao
 * @Date:2020/8/19 15:09
 **/
@Component
@ServerEndpoint("/whwebsocket/{userId}")
public class WebSocket {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    private static Map<String, WebSocket> map = new ConcurrentHashMap<>();

    private Session session;

    private String userId;

    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
        this.session = session;
        this.userId = userId;
        map.put(this.userId, this);
        System.out.println(userId + "连接");
    }

    @OnClose
    public void onClose() {
        map.remove(this.userId);
        System.out.println(userId + "离开");
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        logger.info("服务器发生错误:" + throwable.getMessage());
    }


    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("来自客户端" + session.getId() + "的消息:" + message);
        logger.info("--------------------");
        sendMessageAll(message);
    }

    public void sendMessageAll(String message) {
        for (String user : map.keySet()) {
            if (!user.equals(userId)) {
                map.get(user).session.getAsyncRemote().sendText(message);
            }
        }
    }
}

前端

<template>
  <div>
    聊天室<br />
    <hr />
    <div id="message">
    </div>
    <hr />
    <input type="text"
           id="text">
    <button @click="websocketSendMessage">发送消息</button>
  </div>

</template>
<script>
export default {
  data () {
    return {
      websocket: null
    }
  },
  created () {
    this.initwebsocket()
  },
  methods: {
    initwebsocket () {
      if ('WebSocket' in window) {
        this.websocket = new WebSocket('ws://wanghao6x.free.idcfengye.com/wh/whwebsocket/' + (new Date()).valueOf())
        this.websocket.onopen = this.websocketOnOpen
        this.websocket.onclose = this.websocketOnClose
        this.websocket.onerror = this.websocketOnError
        this.websocket.onmessage = this.websocketOnMessage
      } else {
        alert('Not support websocket')
      }
    },
    websocketOnOpen () {
      console.info('连接')
    },
    websocketOnClose () {
      console.info('关闭')
    },
    websocketOnError (e) {
      console.info('错误')
    },
    websocketOnMessage (e) {
      console.info('接收消息')
      console.info(e.data)
      this.showMessage(e.data)
    },
    websocketSendMessage () {
      console.info('发送消息')
      const message = document.getElementById('text').value
      this.websocket.send(message)
      this.showMessage(message)
    },
    showMessage (innerHTML) {
      document.getElementById('message').innerHTML += innerHTML + '<br/>'
    }
  }
}
</script>

前端必要配置
在这里插入图片描述
在根目录(src同级)下创建vue.config.js文件
内容为

module.exports = {
  devServer: {
    disableHostCheck: true

  }
}

不配置其他主机访问页面时可能出现
Invalid Host header 服务器域名访问出现的问题
参考
https://www.cnblogs.com/liubingboke/p/10939210.html

ngrok

1:后端
在这里插入图片描述
在这里插入图片描述

2:前端是
http://wanghaox.free.idcfengye.com/ 对应8080端口
在这里插入图片描述

界面效果

本机localhost访问
在这里插入图片描述
其他主机访问
在这里插入图片描述
本机发送消息:1
在这里插入图片描述
其他主机接收
在这里插入图片描述
其他主机发送消息:2
在这里插入图片描述
本机接收
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用Spring Boot、Vue.js和WebSocket实现聊天室的代码示例: Spring Boot后端代码: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new WebSocketHandler(), "/chat").setAllowedOrigins("*"); } @Bean public ObjectMapper objectMapper() { return new ObjectMapper(); } } class WebSocketHandler extends TextWebSocketHandler { private static final Map<WebSocketSession, String> users = new ConcurrentHashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) { users.put(session, "Anonymous"); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { ChatMessage chatMessage = new ObjectMapper().readValue(message.getPayload(), ChatMessage.class); if (chatMessage.getType() == ChatMessage.MessageType.JOIN) { users.put(session, chatMessage.getSender()); } for (WebSocketSession user : users.keySet()) { user.sendMessage(new TextMessage(new ObjectMapper().writeValueAsString(chatMessage))); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { users.remove(session); } } @Data @AllArgsConstructor @NoArgsConstructor class ChatMessage { public enum MessageType { CHAT, JOIN, LEAVE } private String sender; private String content; private MessageType type; public static ChatMessage joinMessage(String sender) { return new ChatMessage(sender, "", MessageType.JOIN); } public static ChatMessage leaveMessage(String sender) { return new ChatMessage(sender, "", MessageType.LEAVE); } } @RestController public class ChatController { @GetMapping("/users") public List<String> users() { return new ArrayList<>(WebSocketHandler.users.values()); } } ``` Vue.js前端代码: ```html <template> <div> <h2>Chat Room</h2> <div> <label>Your name:</label> <input v-model="name" @keyup.enter="join" /> <button @click="join">Join</button> </div> <div v-if="joined"> <div> <label>Message:</label> <input v-model="message" @keyup.enter="send" /> <button @click="send">Send</button> </div> <div> <h3>Users:</h3> <ul> <li v-for="user in users" :key="user">{{ user }}</li> </ul> </div> <div> <h3>Chat:</h3> <ul> <li v-for="chat in chats" :key="chat.id"> <strong>{{ chat.sender }}:</strong> {{ chat.content }} </li> </ul> </div> </div> </div> </template> <script> import SockJS from "sockjs-client"; import Stomp from "stompjs"; export default { data() { return { name: "", message: "", joined: false, chats: [], users: [], stompClient: null, }; }, methods: { join() { const socket = new SockJS("/chat"); this.stompClient = Stomp.over(socket); this.stompClient.connect({}, () => { this.stompClient.subscribe("/topic/chat", (message) => { const chat = JSON.parse(message.body); if (chat.type === "JOIN") { this.users.push(chat.sender); } else if (chat.type === "LEAVE") { this.users.splice(this.users.indexOf(chat.sender), 1); } this.chats.push(chat); }); this.stompClient.send( "/app/chat", JSON.stringify(ChatMessage.joinMessage(this.name)) ); this.joined = true; }); }, send() { this.stompClient.send( "/app/chat", JSON.stringify( new ChatMessage(this.name, this.message, ChatMessage.MessageType.CHAT) ) ); this.message = ""; }, }, }; class ChatMessage { static MessageType = { CHAT: "CHAT", JOIN: "JOIN", LEAVE: "LEAVE", }; constructor(sender, content, type) { this.sender = sender; this.content = content; this.type = type; } static joinMessage(sender) { return new ChatMessage(sender, "", ChatMessage.MessageType.JOIN); } static leaveMessage(sender) { return new ChatMessage(sender, "", ChatMessage.MessageType.LEAVE); } } </script> ``` 在这个示例中,我们使用了Spring Boot的WebSocket支持来处理来自客户端的事件。我们创建了一个WebSocket处理程序,它维护了一个用户会话列表,并在用户加入、离开或发送聊天消息时广播消息到所有连接的客户端。我们还为WebSocket处理程序创建了一个控制器,以便在客户端请求所有当前连接的用户列表时返回它们。 在Vue.js应用程序中,我们使用SockJS和Stomp.js来建立与服务器的WebSocket连接,并处理来自服务器的事件。我们使用Vue.js的数据绑定来更新聊天消息、用户列表和用户输入框中的数据,并在加入聊天室、发送聊天消息或断开连接时发送相关的WebSocket事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值