User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • PostgreSQL
    • OAuth2
    • NOSQL
    • MySQL
    • MyBatis
    • More
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • Enamiĝu al vi
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • 666资源站
    • Java 全栈知识体系
    • 尼恩架构师学习
Help?

Please contact us on our email for need any support

Support
    首页   ›   Web   ›   WebSocket   ›   正文
WebSocket

WebSocket(三)—群聊

2020-04-16 00:08:34
341  0 0

参考目录

  • 创建Web项目
  • 创建HTML页面
  • 创建WebSocket服务端

阅读完需:约 6 分钟

我们先来看看我们今天要实现的效果:

创建Web项目

这里和上文(WebSocket刨根问底(二) )一样,web项目创建成功之后,还是要我们先手动添加websocket的jar包进来,添加方式如果小伙伴不懂的话可以参考上篇文章。

http://www.enmalvi.com/2020/04/16/websocket%e4%ba%8c/

创建HTML页面

页面的效果效果小伙伴们刚才都看到了,我这里就直接上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ws页面</title>
    <script src="jquery-3.2.1.js"></script>
</head>
<body>
<input type="text" placeholder="请输入您的昵称" id="nickname"><input type="button" value="连接" id="btnClick1">
</div>
<div id="resultDiv"></div>
<div><input type="text" id="msg"><input type="button" value="发送" id="btnClick2" disabled="disabled"></div>
<script>
    var webSocket;
    $("#btnClick2").click(function () {
        var msg = $("#msg").val();
        $("#msg").val('');
        webSocket.send(msg)
    });
    $("#btnClick1").click(function () {
        var nickname = $("#nickname").val();
        if(nickname==null||nickname=='') {
            alert("必须输入昵称");
            return;
        }
        $("#btnClick2").removeAttr("disabled");
        $(this).attr("disabled", "disabled");
        $("#resultDiv").append("<p>开始连接服务端!</p>");
        webSocket = new WebSocket("ws://localhost/myws2/"+nickname);
        webSocket.onerror = function (event) {
            $("#resultDiv").append("<p>onerror:" + event.data + "</p>");
        }
        webSocket.onopen = function (event) {
            $("#resultDiv").append("<p>连接成功!</p>");
        }
        webSocket.onmessage = function (event) {
            $("#resultDiv").append("<p>" + event.data + "</p>");
        }
    });
</script>
</body>
</html>

关于这段HTML代码,我说如下几点:

1.一开始发送按钮处于不可用状态,必须先连接 
2.连接时必须先输入昵称,如果不输入昵称则弹出提示 
3.连接成功之后连接按钮处于不可点击状态而发送按钮处于可点击状态 
4.在连接按钮的点击事件中初始化WebSocket对象以及WebSocket中涉及到的一些方法的初始化 
5.所有的信息(连接成功,连接出错以及接收到消息)最后都显示在resultDiv中 
6.连接地址是动态变化的,最后的字符是连接的用户名

OK,这里的代码都很简单,我就不一一解释了。

创建WebSocket服务端

由于我们这里要做的是群聊,所以服务端的主要功能就是接收客户端传来的消息并将之广播给所有的客户端。服务端代码如下:

@ServerEndpoint("/myws2/{nickname}")
public class WebSocketServer2 {
    private String nickname;
    private Session session;
    private static final Set<WebSocketServer2> WEB_SOCKET_SERVER_2_SET = new CopyOnWriteArraySet<WebSocketServer2>();

    @OnMessage
    public void onMessage(String message, @PathParam(value = "nickname") String nickname) throws IOException {
        System.out.println("收到了客户端发来的消息:" + message);
        sendText(nickname+"发来了:"+message);
    }

    private static void sendText(String msg) {
        for (WebSocketServer2 webSocketServer2 : WEB_SOCKET_SERVER_2_SET) {
            try {
                synchronized (webSocketServer2) {
                    webSocketServer2.session.getBasicRemote().sendText(msg);
                }
            } catch (IOException e) {
                WEB_SOCKET_SERVER_2_SET.remove(webSocketServer2);
                try {
                    webSocketServer2.session.close();
                } catch (IOException e1) {
                }
                sendText(webSocketServer2.nickname + "同学已经下线");
            }
        }
    }

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "nickname") String nickname) throws IOException {
        this.nickname = nickname;
        this.session = session;
        WEB_SOCKET_SERVER_2_SET.add(this);
        sendText(nickname + "进入房间");
        StringBuffer sb = new StringBuffer();
        for (WebSocketServer2 webSocketServer2 : WEB_SOCKET_SERVER_2_SET) {
            sb.append(webSocketServer2.nickname).append(";");
        }
        sendText("当前房间有:"+sb.toString());
    }

    @OnClose
    public void onClose(Session session) throws IOException {
        WEB_SOCKET_SERVER_2_SET.remove(this);
        sendText(this.nickname+"童鞋已下线");
    }
}

这个服务端解释如下几点:

1.第一行的代码表示服务端的名字,但是名字里边有一个{nickname},表示获取服务端传递来的最后一个参数,在方法里边可以通过@PathParam来获取,这个和SpringMVC的参数注解如出一辙 
2.第三行和第四行创建了两个对象,因为当客户端脸上服务端之后,一个客户端将对应一个WebSocketServer2对象,我需要将每一个客户端的有关信息保存下来,因此创建出nickname表示该对象对应的客户端的用户昵称,session表示该对象对应的客户端的session 
3.第五行创建一个Set集合,该集合是static final类型的,表示不管WebSocketServer2的对象有多少个,WEB_SOCKET_SERVER_2_SET集合始终是同一个,该集合主要用来保存所有连接的客户端对应的WebSocketServer2对象 
4.第30行到41行是open方法的逻辑,该方法有两个参数,第一个session,第二个nickname,nickname参数有一个注解@PathParam表示该参数的值就是连接地址里边的最后一个字符串,这个参数是可选的。在该方法里,首先将nickname和session赋值给对应的全局变量,然后将当前对象添加到set集合中,然后调用sendText方法发送一条消息,告诉所有的客户端XXX进入房间啦,最后遍历set集合中的所有用户,拿到所有用户的用户名,再告诉所有客户端当前的房间都有谁谁谁。 
5.第13-28行的sendText方法是一个自定义的静态方法,该方法主要用来向所有的客户端广播消息,该方法的基本逻辑就是遍历set集合,拿到set集合中的每一个对象和每一个对象中的session,再利用session向对应的客户端发送消息,如果消息发送失败,则将该用户从集合中移除,同时告诉剩余的客户端某某人已经下线。 
6.第7-10行的代码主要用来处理客户端发送来的消息,默认的String类型的参数表示客户端发送来的消息,其他的String类型参数都要加上注解才可以,我们这里第一个参数表示客户端发送来的消息,第二个参数表示发送客户端消息的用户昵称,这里收到消息之后,再利用sendText广播给所有用户。 
7.第43行到47行表示当其中一个用户下线了了会回调的close方法,在这里方法里首先从集合中移除该客户端对应的WebSocketServer2对象,然后广播一条消息将该用户下线的事告诉所有人。

OK,经过以上7点的讲解,小伙伴们对服务端的代码应该是非常熟悉了吧~

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
一个人若有一百只羊,一只走迷了路,你们的意思如何?他岂不撇下这九十九只,往山里去找那只迷路的羊吗?
509文章 66评论 154点赞 267341浏览
默认版本~SpringBoot2.0~2.3
  • Spring—WebClient使用
  • SpringCloud—LoadBalanced负载均衡
  • Spring—ApplicationEvent事件驱动机制
  • SpringMVC—Web九大组件之HandlerExceptionResolver异常处理器
  • SpringMVC—ModelAndViewContainer、ModelMap、Model、ModelAndView、@ModelAttribute、@SessionAttribute等
  • SpringMVC—Web九大组件之ViewResolver
  • SpringMVC—ContentNegotiation内容协商机制
随便看看就好
ActiveMQ (4) Ajax (13) Consul (1) Docker (7) ElasticSearch (13) Enamiĝu al vi (1) Eureka (2) Feign (6) Freemarker (5) Gateway (6) Git (5) Hystrix (7) Java (71) Java Notes (110) JavaScript (1) jQuery (2) Kotlin Notes (47) LoadBalancer (1) Maven (2) More (0) MyBatis (41) MySQL (5) OAuth2 (11) PostgreSQL (4) RabbitMQ (6) Redis (17) Ribbon (6) Servlet (3) Spring (68) SpringBoot (83) SpringCloud (14) SpringJPA (4) SpringMVC (46) Spring Notes (43) SpringSecurity (49) SQL (13) SQL Notes (9) SQL Server (2) Thymeleaf (4) Vue (9) Web (12) Web Notes (18) WebSocket (9) XML (1) Zuul (3)
随便看看就好
  • 2023年1月 (3)
  • 2022年12月 (1)
  • 2022年11月 (3)
  • 2022年10月 (5)
  • 2022年9月 (8)
  • 2022年8月 (1)
  • 2022年7月 (2)
  • 2022年6月 (4)
  • 2022年5月 (5)
  • 2022年4月 (3)
  • 2022年3月 (7)
  • 2022年2月 (4)
  • 2022年1月 (15)
  • 2021年12月 (16)
  • 2021年11月 (3)
  • 2021年10月 (3)
  • 2021年9月 (3)
  • 2021年8月 (2)
  • 2021年7月 (4)
  • 2021年6月 (16)
  • 2021年5月 (3)
  • 2021年4月 (2)
  • 2021年3月 (13)
  • 2021年2月 (2)
  • 2021年1月 (33)
  • 2020年12月 (13)
  • 2020年11月 (6)
  • 2020年10月 (17)
  • 2020年9月 (26)
  • 2020年8月 (46)
  • 2020年7月 (28)
  • 2020年6月 (4)
  • 2020年5月 (16)
  • 2020年4月 (88)
  • 2020年3月 (104)
随机文章
Kotlin-表达式—分支表达式(十二)
2年前
Git基操学习—2
3年前
SpringSecurity—从子线程获取用户登录信息
2年前
Spring Boot 项目中的 parent
3年前
MyBatis笔记13—一对一查询
3年前
ENMAL摘要

1、Kotlin:

https://www.liuwj.me/

 

2、webflux:

https://www.cnblogs.com/lixinjie/p/a-brother-of-spring-mvc-is-spring-webflux.html

 

3、Java中的Unsafe

 

4、https://my.oschina.net/quanke/blog/1631990

 

5、https://blog.csdn.net/u013064109/article/details/78786646?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161214257916780264022540%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161214257916780264022540&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-11-78786646.first_rank_v2_pc_rank_v29&utm_term=kotlin

 

6、待学习除Spring之外的Web框架 — Cloudopt Next、Javalin、jfinal

https://jfinal.com/doc

 

7、kotlin设计模式——https://github.com/AboutKotlin/Design-Patterns-In-Kotlin

 

8、kotlin–ktorm+SpringBoot——https://gitee.com/tianchaohongyu/Spring-Boot-Ktor-Starter

 

9、新技术 — CQRS、jasync-sql、play!framework、akka、asyncdb

 

10、Kotlin Tips

https://gitee.com/lesliekoma/kotlin_tips?_from=gitee_search#tip5–%E6%87%92%E5%88%9D%E5%A7%8B%E5%8C%96by-lazy-%E5%92%8C-%E5%BB%B6%E8%BF%9F%E5%88%9D%E5%A7%8B%E5%8C%96lateinit

 

11、mall项目电商系统

https://github.com/macrozheng/mall

 

12、POI大量读写

https://www.cnblogs.com/swordfall/p/8298386.html

 

13、Gitee

权限RBAC:

https://gitee.com/log4j/pig

 

14、freecodecamp、pf4j

 

15、https://javadoop.com/

 

16、https://www.cnblogs.com/skywang12345/

 

17、Flyway

 

18、https://github.com/kotlin-orm/ktorm/pull/296

 

kt实体类自动生成表

 

https://github.com/tursom/TursomServer/tree/master/ts-database/src/main/kotlin/cn/tursom/database

 

19、蓝狐、支付沙盒、虚拟币

 

20、r2dbc spring强推,vertx这边是quarkus强推 redhat认证

 

21、Keycloak为Web应用和Restful服务提供了一站式的单点登录解决方案。

 

22、RSQL 的形式为 Restful API 带来了 SQL 声明性的便利

https://github.com/vineey/archelix-rsql

https://github.com/ymind/rsql-ktorm

 

23、Kotlin依赖注入

https://github.com/InsertKoinIO/koin

 

24、Kotlin– Alpas

https://github.com/alpas/alpas

一个基于 Kotlin 的 Web 框架,可让您简单快速地创建 Web 应用程序和 API。

 

25、外网学习网站,文章

https://medium.com/nerd-for-tech

 

26、Compose Multiplatform 进入 Alpha 版,统一桌面、Web 和 Android UI

https://blog.jetbrains.com/kotlin/2021/08/compose-multiplatform-goes- alpha/

 

27、Sureness

面向REST API的高性能认证鉴权框架,致力于管理保护API安全

https://gitee.com/dromara/sureness

与Javalin结合

https://javalin.io/2021/04/16/javalin-sureness-example.html

 

28、Kotlin官网合集库

https://kotlinlang.org/lp/server-side/

https://kotlinlang.org/lp/server-side/

https://kotlinlang.org/lp/server-side/

 

29、CLI知识体系

https://juejin.cn/post/6966119324478079007

 

30、面向 Web、移动和 Flutter 开发人员的安全开源后端服务器

https://appwrite.io/

 

31、Java锁

https://blog.csdn.net/hancoder/article/details/120421993

 

32、java—简单的鉴权认证

介绍 – Sa-Token (dev33.cn)

 

33、Effective Kotlin 中文翻译

GitHub – MaxzMeng/Effective-Kotlin-zh-CN: Effective Kotlin 中文翻译

 

34、Nutz—国产Web开源框架

http://www.nutzam.com/core/nutz_preface.html

 

35、Quarkus 夸克—国外开源框架

https://quarkus.io/

 

36、目前6个框架

  1. Spring Reactive → 背靠 Pivotal → 归属 VMware → 归属戴尔
  2. Quarkus 和 Vert.x → 背靠 Eclipse 基金会 → 主要由 Red Hat 支持
  3. Helidon → 背靠 Oracle
  4. Micronaut → 背靠 Object Computing(Grails、OpenDDS)
  5. Lagom → 背靠 Lightbend(Akka)
  6. Ktor → 背靠 JetBrains

 

37、XXL-JOB—–分布式任务调度平台

https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%B9%B3%E5%8F%B0XXL-JOB%E3%80%8B

 

38、领域设计驱动模版

https://myddd.org

 

39、BFF— Backend For Frontend

 

40、面试突击小册

https://snailclimb.gitee.io/javaguide-interview/#/

https://javaguide.cn/

 

41、JeecgBoot 是一款基于代码生成器的低代码开发平台

http://doc.jeecg.com/2043868

 

42、

IdentityServer4 是用于 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 框架。

https://identityserver4docs.readthedocs.io/zh_CN/latest/index.html

 

43、cn.novelweb 工具类的个人博客

https://blog.novelweb.cn

 

44、分布式链路追踪SkyWalking

 

45、刷题模版

https://blog.csdn.net/fuxuemingzhu/article/details/101900729

 

46、TS中文文档

https://ts.xcatliu.com/

 

47、Rust 中文文档

https://kaisery.github.io/trpl-zh-cn/ch00-00-introduction.html

 

48、Bean Searcher 只读 ORM

https://searcher.ejlchina.com/guide/latest/start.html

 

49、K8S的学习手册

https://kuboard.cn/learning/k8s-basics/kubernetes-basics.html#%E5%AD%A6%E4%B9%A0%E7%9B%AE%E6%A0%87

 

50、fluent-mybatis, mybatis语法增强框架(关键自动生成代码JavaPoet)

https://gitee.com/fluent-mybatis/fluent-mybatis?_from=gitee_search

 

51、程序猿博客

https://qicoder.com/categories/

https://blog.hhui.top/hexblog/

https://fangshixiang.blog.csdn.net/category_7941357_2.html

https://www.zhihu.com/people/zhuo-zi-yang-93

 

52、itxiaoshen大佬的分享

https://www.cnblogs.com/itxiaoshen/

Copyright © 2023 网站备案号: 浙ICP备20017730号
主页
页面
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
If you get tired, learn to rest, not to quit.
509 文章 66 评论 267341 浏览
测试
测试
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付