当前位置: 首页 > news >正文

网站运营经验分享ppt宿迁网站建设电话

网站运营经验分享ppt,宿迁网站建设电话,怎么看小企业网站建设,网站模版上线需要什么目录 前言 注解式 WebSocket 构建聊天系统 群聊系统#xff08;基本框架#xff09; 群聊系统#xff08;添加昵称#xff09; 单聊系统 WebSocket 作用域下无法注入 Spring Bean 对象#xff1f; 考虑离线消息 前言 很久之前#xff0c;咱们聊过 WebSocket 编程式…目录 前言 注解式 WebSocket 构建聊天系统 群聊系统基本框架 群聊系统添加昵称 单聊系统 WebSocket 作用域下无法注入 Spring Bean 对象 考虑离线消息 前言 很久之前咱们聊过 WebSocket 编程式的写法但是有些过于繁琐这次来看看更接近现代的注解式构建 群聊、单聊 有多么便利. 注解式 WebSocket 构建聊天系统 群聊系统基本框架 a定义 WebSocket 配置类. import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.web.socket.server.standard.ServerEndpointExporter/*** 注入对象 ServerEndpointExporter* 这个 bean 会自动注册使用了 ServerEndpoint 注解声明的 WebSocket endpoint*/Configuration class WebSocketConfig {Beanfun serverEndpointExporter() ServerEndpointExporter()}bWebSocket 实现类 import org.springframework.stereotype.Component import java.util.concurrent.CopyOnWriteArraySet import javax.websocket.OnClose import javax.websocket.OnError import javax.websocket.OnMessage import javax.websocket.OnOpen import javax.websocket.Session import javax.websocket.server.ServerEndpoint/*** 虽然此处 Component 默认是单例的但是 SpringBoot 还是会为每个 WebSocket 初始化一个 bean* 因此可以使用一个静态的 Set 保存起来(CopyOnWriteArraySet 相比于 HashSet 是线程安全的)*/ ServerEndpoint(value /websocket) Component class MyWebSocket {companion object {//用来存放每个客户端对应的 MyWebSocket 对象private val webSocketSet CopyOnWriteArraySetMyWebSocket()}//与某个客户都安连接的会话需要通过他来给客户都安发送数据private lateinit var session: Session/*** 连接成功调用的方法*/OnOpenfun onOpen(session: Session) {//获取当前连接客户端 sessionthis.session session//加入到 set 中webSocketSet.add(this)println(当前在线人数为: ${webSocketSet.size})this.session.asyncRemote.sendText(恭喜您成功连接上 WebSocket当前在线人数为: ${webSocketSet.size})}/*** 收到客户端消息时调用的方法*/OnMessagefun onMessage(message: String, session: Session) {println(收到客户端的消息: $message)//群发消息allSend(message)}OnErrorfun onError(session: Session, error: Throwable) {println(连接异常)error.printStackTrace()}OnClosefun onClose() {webSocketSet.remove(this)println(有人下线当前在线人数: ${webSocketSet.size})}/*** 自定义群发消息* basicRemote: 阻塞式* asyncRemote: 非阻塞式* 大部分情况下更推荐使用 asyncRemote 详情: https://blog.csdn.net/who_is_xiaoming/article/details/53287691*/private fun allSend(message: String) {webSocketSet.forEach {//it.session.basicRemote.sendText(message)it.session.asyncRemote.sendText(message)}}}c客户端开发 !DOCTYPE HTML htmlheadmeta charsetUTF-8titleMy WebSocket/titlestyle#message {margin-top: 40px;border: 1px solid gray;padding: 20px;}/style /headbodybutton onclickconectWebSocket()连接WebSocket/buttonbutton onclickcloseWebSocket()断开连接/buttonhr /br /消息input idtext typetext /button onclicksend()发送消息/buttondiv idmessage/div /body script typetext/javascriptvar websocket null;function conectWebSocket() {//判断当前浏览器是否支持WebSocketif (WebSocket in window) {websocket new WebSocket(ws://localhost:9000/websocket);} else {alert(Not support websocket)}//连接发生错误的回调方法websocket.onerror function () {setMessageInnerHTML(error);};//连接成功建立的回调方法websocket.onopen function (event) {setMessageInnerHTML(tips: 连接成功);}//接收到消息的回调方法websocket.onmessage function (event) {setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose function () {setMessageInnerHTML(tips: 关闭连接);}//监听窗口关闭事件当窗口关闭时主动去关闭websocket连接防止连接还没断开就关闭窗口server端会抛异常。window.onbeforeunload function () {websocket.close();}}//将消息显示在网页上function setMessageInnerHTML(innerHTML) {document.getElementById(message).innerHTML innerHTML br/;}//关闭连接function closeWebSocket() {websocket.close();}//发送消息function send() {var message document.getElementById(text).value;websocket.send(message);}/script/html d效果如下 打开两个浏览器依次点击建立连接 左边的浏览器中输入你好我是 cyk效果如下 群聊系统添加昵称 上述聊天系统中可以看到并不知道当前消息是哪一个用户发出的因此这里我们改造一下让每个消息前携带用户名. a客户端改造在用户点击 连接 WebSocket 之前输入昵称以此作为消息的身份标识. b服务端改造 之后在 WebSocket 注解标记的每一个方法中都可以通过 PathParam(nickname) nickname: String 获取到 nickname. 尽管如此再上图中我还是使用成员变量 nickname 在 WebSocket 第一次建立连接的时候通过 onOpen 标记的方法进行保存. 如下 /*** 连接成功调用的方法*/OnOpenfun onOpen(session: Session,PathParam(nickname) nickname: String) {//获取当前连接客户端 sessionthis.session sessionthis.nickname nickname//加入到 set 中webSocketSet.add(this)println($nickname 上线当前在线人数为: ${webSocketSet.size})allSend(系统消息: $nickname 上线)}发送的消息携带上昵称 OnMessagefun onMessage(message: String, session: Session) {println(收到客户端的消息: $message)//群发消息allSend($nickname: $message)}c效果如下 单聊系统 a服务器开发需要通过一个 map 来记录用户的 session 信息key用户唯一标识value: session ChatMsg用来接收客户端传入的 JSON 消息通过 ObjectMapper 反序列化. onOpen记录用户信息到 map 中. opMessage将消息转发给目标人物. import com.fasterxml.jackson.databind.ObjectMapper import org.springframework.stereotype.Component import java.util.concurrent.ConcurrentHashMap import javax.websocket.OnClose import javax.websocket.OnError import javax.websocket.OnMessage import javax.websocket.OnOpen import javax.websocket.Session import javax.websocket.server.PathParam import javax.websocket.server.ServerEndpointdata class ChatMsg (val targetName: String , //目标val msg: String , //消息 )/*** 虽然此处 Component 默认是单例的但是 SpringBoot 还是会为每个 WebSocket 初始化一个 bean* 因此可以使用一个静态的 Set 保存起来(CopyOnWriteArraySet 相比于 HashSet 是线程安全的)*/ ServerEndpoint(value /websocket/{nickname}) Component class MyWebSocket {companion object {//用来存放每个客户端对应的 MyWebSocket 对象private val webSocketMap ConcurrentHashMapString, Session()}//与某个客户都安连接的会话需要通过他来给客户都安发送数据private lateinit var session: Session //用来记录当前连接者会话private lateinit var nickname: String/*** 连接成功调用的方法*/OnOpenfun onOpen(session: Session,PathParam(nickname) nickname: String) {//获取当前连接客户端 sessionthis.session sessionthis.nickname nickname//加入到 set 中webSocketMap[nickname] sessionprintln($nickname 上线当前在线人数为: ${webSocketMap.size})allSend(系统消息: $nickname 上线)}/*** 收到客户端消息时调用的方法*/OnMessagefun onMessage(messageJson: String, session: Session) {println(收到客户端的消息: $messageJson)//单独发送消息val mapper ObjectMapper()val message mapper.readValue(messageJson, ChatMsg::class.java)val targetSession webSocketMap[message.targetName]val postSession this.sessionif(targetSession null) {postSession.asyncRemote.sendText(当前用户不存在或者不在线)} else {postSession.asyncRemote.sendText(${nickname}: ${message.msg}) //发送者获取自己的消息targetSession.asyncRemote.sendText(${nickname}: ${message.msg}) //接收者获取发送者的消息}}OnErrorfun onError(session: Session, error: Throwable) {println(连接异常)error.printStackTrace()}OnClosefun onClose() {webSocketMap.remove(nickname)println(${nickname} 下线当前在线人数: ${webSocketMap.size})allSend(系统消息: $nickname 下线)}/*** 自定义群发消息* basicRemote: 阻塞式* asyncRemote: 非阻塞式* 大部分情况下更推荐使用 asyncRemote 详情: https://blog.csdn.net/who_is_xiaoming/article/details/53287691*/private fun allSend(message: String) {webSocketMap.forEach {it.value.asyncRemote.sendText(message)}}}b客户端开发 !DOCTYPE HTML htmlheadmeta charsetUTF-8titleMy WebSocket/titlestyle#message {margin-top: 40px;border: 1px solid gray;padding: 20px;}/style /headbodydivspan昵称: /spaninput typetext idnickname/divbutton onclickconectWebSocket()连接WebSocket/buttonbutton onclickcloseWebSocket()断开连接/buttonhr /br /divspantargetName: /spaninput typetext idtargetName/divdivspan消息: /spaninput idtext typetext //divbutton onclicksend()发送消息/buttondiv idmessage/div /body script typetext/javascriptvar websocket null;function conectWebSocket() {//判断当前浏览器是否支持WebSocketif (WebSocket in window) {let nickname document.getElementById(nickname).valueif (nickname null || nickname ) {alert(请先输入昵称)return}websocket new WebSocket(ws://localhost:9000/websocket/ nickname);} else {alert(Not support websocket)}//连接发生错误的回调方法websocket.onerror function () {setMessageInnerHTML(error);};//连接成功建立的回调方法websocket.onopen function (event) {setMessageInnerHTML(tips: 连接成功);}//接收到消息的回调方法websocket.onmessage function (event) {setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose function () {setMessageInnerHTML(tips: 关闭连接);}//监听窗口关闭事件当窗口关闭时主动去关闭websocket连接防止连接还没断开就关闭窗口server端会抛异常。window.onbeforeunload function () {websocket.close();}}//将消息显示在网页上function setMessageInnerHTML(innerHTML) {document.getElementById(message).innerHTML innerHTML br/;}//关闭连接function closeWebSocket() {websocket.close();}//发送消息function send() {var message document.getElementById(text).value;var targetName document.getElementById(targetName).value;var chatMsg {targetName: targetName,msg: message}websocket.send(JSON.stringify(chatMsg));}/script/html WebSocket 作用域下无法注入 Spring Bean 对象 这是因为 Spring 管理 Bean 对象默认都是单例的而 WebSocket 却是多例的因此注入 Spring 中的 Bean 对象会冲突.  解决办法通过 set 方法注入一个静态的 Bean 即可. ServerEndpoint(/websocket/{id}) Component class ChatRoom {companion object {private lateinit var userInfoRepo: UserInfoRepo}Resourcefun setUserInfoRepo(userInfoRepo: UserInfoRepo) {Companion.userInfoRepo userInfoRepo}}考虑离线消息 只需要再添加一个 ConcurrentHashMap 来记录用户和离线消息~  考虑到消息可能过大放在内存中不太合适也可以通过专门设计一个张数据库表来存放用户的离线消息. 当用户再次上线触发 onOpen 方法时就可以恢复离线消息啦~ Ps想要源码可以联系我......
http://www.zqtcl.cn/news/23416/

相关文章:

  • 站长之家工具高清360网站页面的工具栏怎么做
  • 郭仓镇做网站全球电子商务公司排行
  • 看国外网站如何做科普网站设计存在的问题
  • 贵阳哪家网站建设公司好企业做网站时应注意的事项
  • 怎样进行网站后台管理庆阳logo设计
  • 勒流网站建设制作免费ppt模板下载医院
  • 网站实时推送怎么做搜索引擎营销的主要方式有
  • 长沙有哪些做的好一点的网站关于网站规划建设方案书
  • php网站制作过程中遇到的问题及解决办法建网站的成本计算
  • 网站开发的关键绥化市住房和城乡建设网网站
  • 宁波网站的优化标识设计图片
  • 网站建设微信公众号做网站和app哪个难
  • 高密做网站的公司哈尔滨建设部网站
  • 网站建设问题整改报告无锡君通科技服务有限公司
  • 做庭院景观的那个网站推广好phpcms wap网站搭建
  • 如何创办一个赚钱的网站怎么下载网页上的视频
  • 国外优秀人像摄影网站wordpress 福利 源码
  • 做二手房又做网站的手机app快速开发平台
  • 网站开发维护求职信苏州优化外包
  • 江苏网站设计网页设计素材整理分级是什么意思
  • 安徽茶叶网站建设学校网站要求
  • .net网站程序网页设计与制作作业成品免费
  • 做网站l价格中国老区建设促进会网站
  • 网站备案需要拍照备案网站域名被抢注
  • 旅行社建设网站wordpress图片主题
  • 私自建设网站绿色食品网站模板.htm
  • 乐陵市人力资源中心网站西安招聘网最新招聘
  • 怀柔重庆网站建设规模以上工业企业分析
  • h5建站是什么怎么自己做网站服务器
  • 中国建设银行掌上银行官方网站网上可以报警备案吗