{"id":19215045,"url":"https://github.com/chgl16/chatroom","last_synced_at":"2025-05-12T23:22:07.898Z","repository":{"id":107504182,"uuid":"162398943","full_name":"chgl16/chatroom","owner":"chgl16","description":":pencil: 基于Spring Boot+WebSocket(STOMP) web聊天系统。支持点对点和广播发送消息，Spring Security 单点登录验证","archived":false,"fork":false,"pushed_at":"2019-02-25T13:23:12.000Z","size":27140,"stargazers_count":12,"open_issues_count":0,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-20T19:37:21.695Z","etag":null,"topics":["chat-room","spring-boot","websocket-chat"],"latest_commit_sha":null,"homepage":"http://www.cglzwz.xyz:9999","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chgl16.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-12-19T07:26:08.000Z","updated_at":"2023-06-05T14:36:45.000Z","dependencies_parsed_at":"2023-05-17T15:15:28.250Z","dependency_job_id":null,"html_url":"https://github.com/chgl16/chatroom","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgl16%2Fchatroom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgl16%2Fchatroom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgl16%2Fchatroom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chgl16%2Fchatroom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chgl16","download_url":"https://codeload.github.com/chgl16/chatroom/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253838094,"owners_count":21972091,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat-room","spring-boot","websocket-chat"],"created_at":"2024-11-09T14:12:34.683Z","updated_at":"2025-05-12T23:22:07.890Z","avatar_url":"https://github.com/chgl16.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chatroom\n    基于WebSocket子协议STOMP实现的WEB端点对点实时聊天系统\n\n\u003cbr\u003e\n\n## 开发环境\n![JAVA](https://img.shields.io/badge/Java-1.8-green.svg) \n![Maven](https://img.shields.io/badge/Maven-3.5-orange.svg)\n![Spring Boot](https://img.shields.io/badge/Spring.Boot-2.1.1-green.svg)\n![Spring Security](https://img.shields.io/badge/Spring.Security-5.1-green.svg)\n\n![Thymeleaf](https://img.shields.io/badge/Thymeleaf-3-yellow.svg)\n![MyBatis](https://img.shields.io/badge/MyBatis-3+-color.svg)\n![MySQL](https://img.shields.io/badge/MySQL-5.7-blue.svg)\n![jQuery](https://img.shields.io/badge/jQuery-3.3.1-brown.svg)\n![bootstrap](https://img.shields.io/badge/Bootstrap-4.1.3-purple.svg)\n\n\u003cbr\u003e\n\n## 启动项目\n    开发环境8080端口，线上环境9999端口(先配好数据库)\n\n```xml\nmvn spring-boot:run \n```\n 或者\n```xml\nmvn clean package\njava -jar target/*.jar\n```\n\n服务器\n```shell\njava -jar *.jar \u003e log 2\u003e\u00261 \u0026 \n```\n\n\u003cbr\u003e\n\n## 效果预览\n![登录](img-folder/login.png)\n\u003chr\u003e\n\n![注册](img-folder/register.png)\n\u003chr\u003e\n\n![首页](img-folder/index.png)\n\u003chr\u003e\n\n![广播](img-folder/chat1.png)\n\u003chr\u003e\n\n![聊天](img-folder/chat2.png)\n\n## 关键实现\n1. 注册一个WebSocket\n```java\n@Configuration\n@EnableWebSocketMessageBroker\npublic class WebSocketConfig implements WebSocketMessageBrokerConfigurer {\n    @Override\n    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {\n        // 添加一个名为 \"/endpointChat\" 的基于STOMP子协议的节点（即服务器端socket）\n        stompEndpointRegistry.addEndpoint(\"/endpointChat\").withSockJS();\n    }\n}\n```\n2. 自定义数据库方式认证\n```java\n@Service\npublic class CustomUserService implements UserDetailsService {\n    private static final Log log = LogFactory.getLog(CustomUserService.class);\n\n    @Autowired\n    private UserMapper userMapper;\n\n    /**\n     * 重写 loadUserByUsername 方法获取 userDetails 类型用户\n     * SysUser 已经实现 UserDetails\n     *\n     * @param username\n     * @return\n     * @throws UsernameNotFoundException\n     */\n    @Override\n    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {\n        SysUser user = userMapper.findByUsername(username);\n        if (user != null) {\n            log.info(\"username存在\");\n            log.info(\"打印: \" + user);\n\n            // 用户权限\n            List\u003cSimpleGrantedAuthority\u003e authorities = new ArrayList\u003c\u003e();\n            //用于添加用户的权限。只要把用户权限添加到authorities[本项目固定是用户角色]\n            authorities.add(new SimpleGrantedAuthority(\"ROLE_USER\"));\n\n            return new org.springframework.security.core.userdetails.User(user.getUsername(),\n                    user.getPassword(), authorities);\n        } else {\n            throw new UsernameNotFoundException(\"admin: \" + username + \" do not exist!\");\n        }\n    }\n}\n```\n3. WebSecurityConfig中配置数据库认证授权\n```java\n@Configuration\n@EnableWebSecurity\npublic class WebSecurityConfig extends WebSecurityConfigurerAdapter {\n    @Bean\n    UserDetailsService myCustomUserService() {\n        return new CustomUserService();\n    }\n\n    @Override\n    protected void configure(AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(myCustomUserService());\n    }\n    ....\n}\n```\n4. 前端socket连接订阅\n```javascript\nvar sock = new SockJS(\"/chatroom/endpointChat\");\nvar stomp = Stomp.over(sock);\nstomp.connect('guest', 'guest', function (frame) {\n    stomp.subscribe(\"/user/notification\", showGetMsg);\n});\n```\n5. 消息发送\n```javascript\nstomp.send(\"/chat\", {}, JSON.stringify({\"text\": text, \"receiver\": receiver}));\n```\n6. 服务器相应转发\n```java\n@MessageMapping(value = \"/chat\")\npublic void handleChat(Principal principal, Message message) {\n    if (message.getReceiver().equals(\"\")) {\n        log.info(\"不填接收者，这是广播\");\n        simpMessagingTemplate.convertAndSendToUser(\"\", \"/notification\",  \n            \"@广播(\" + principal.getName() + \"): \" + message.getText());\n    } else {\n        simpMessagingTemplate.convertAndSendToUser(message.getReceiver(), \"/notification\",  \n            principal.getName() + \": \" + message.getText());\n    }\n}\n```\n\n## 有待更新\n1. 登录login后的请求都交付Spring Security处理了，中间没有做拦截，因此登录成功后无法获取个人信息\n2. 用户回话session保持功能没有实现\n3. 聊天界面信息现象、分组、房间等功能有待添加优化\n\n\n## 问题博客\n    开发中遇到的问题在CSDN博客上记录了些\n1. [spring Boot配置开发、线上环境](https://blog.csdn.net/chenbetter1996/article/details/85071430)\n2. [Spring Security 5禁止明文、加密问题](https://blog.csdn.net/chenbetter1996/article/details/85080790)\n3. [Spring Boot结合Thymeleaf静态资源拦截](https://blog.csdn.net/chenbetter1996/article/details/85092531)\n4. [Spring Boot 2.0新版配置虚拟访问路径](https://blog.csdn.net/chenbetter1996/article/details/85268748)\n5. [jar包服务器常驻后台执行](https://blog.csdn.net/chenbetter1996/article/details/85274988)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchgl16%2Fchatroom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchgl16%2Fchatroom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchgl16%2Fchatroom/lists"}