目录

一、简介

二、java服务端

1、引入包

2、配置

3、代码实现

三、H5客户端

1、代码实现

一、简介

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

现在,很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。

在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

二、java服务端

1.引入包(gradle管理)

compile 'org.springframework.boot:spring-boot-starter-websocket:2.0.4.RELEASE'

2.配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** 简介:** @Author: hzj* @Date: 2019/7/8 0008 17:44*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

3.代码实现

import com.getoncar.common.exception.BaseException;
import com.getoncar.common.exception.CustomException;
import com.getoncar.entity.Agent_Entity;
import com.getoncar.entity.Message_Entity;
import com.getoncar.host.agent.config.websupport.ResponseVo;
import com.getoncar.model.AgentSendDialogueRequest;
import com.getoncar.model.MessageModel;
import com.getoncar.service.MessageAgentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.EOFException;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import static com.getoncar.service.MessageAgentService.oneMessageCache;/*** 简介:** @Author: hzj* @Date: 2019/7/9 0009 9:05*/
@Slf4j
@Api(description ="websocket对话中心-hzj")
@RequestMapping(value = "/websocketController")
@ServerEndpoint(value = "/websocket/{userId}")
@Component    //此注解千万千万不要忘记,它的主要作用就是将这个监听器纳入到Spring容器中进行管理
@RestController
public class WebSocketController {//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。public static int onlineCount = 0;//concurrent包的线程安全Set[ConcurrentHashMap],用来存放每个客户端对应的MyWebSocket对象。public static ConcurrentHashMap<String,WebSocketController> webSocketSet = new ConcurrentHashMap<>();//与某个客户端的连接会话,需要通过它来给客户端发送数据public Session session;//接收参数中的用户IDpublic Long userId;//接收用户中的平台类型public Long platformType;public Session getSession() {return session;}public void setSession(Session session) {this.session = session;}private static ExecutorService executorService = Executors.newCachedThreadPool();private static MessageAgentService messageService;@Autowiredpublic void setMessageService(MessageAgentService messageService) {WebSocketController.messageService = messageService;}@ApiOperation(value ="服务器群发消息")@ApiImplicitParams(@ApiImplicitParam(paramType = "query",name = "content",value = "消息内容",dataType = "String"))@GetMapping("/ServerSendInfo")public void ServerSendInfo(String content) throws IOException {sendInfos("这是服务器给你推送的消息:"+content);}/*** 连接建立成功调用的方法* 接收url中的参数*/@OnOpenpublic void onOpen(Session session,@PathParam("userId") Long userId) {log.info("进入websocket连接");if(webSocketSet.containsKey(userId+"")){log.info("重复登陆-"+userId);try {WebSocketController before = webSocketSet.get(userId+"");if(before.getSession().isOpen()){log.info("发送被迫下线通知");before.getSession().getBasicRemote().sendText("你的会话再另一地方登陆,被迫下线");before.getSession().close();//关闭会话}webSocketSet.remove(before);log.info("重复登陆"+userId+"连接"+before.getSession().getId()+"被服务器主动关闭!当前在线人数为" + getOnlineCount());} catch (IOException e) {e.printStackTrace();return;}}int maxSize = 200 * 1024; // 200K// 可以缓冲的传入二进制消息的最大长度session.setMaxBinaryMessageBufferSize(maxSize);// 可以缓冲的传入文本消息的最大长度session.setMaxTextMessageBufferSize(maxSize);this.session = session;this.userId = userId;this.platformType = platformType;webSocketSet.put(userId+"",this);     //加入set中addOnlineCount();           //在线数加1log.info("有新连接加入!当前在线人数为" + getOnlineCount() + "  userId==== " + userId + "  platformType==== " + platformType);
//        try {
//            sendMessage("连接成功");
//        } catch (IOException e) {
//            log.error("websocket IO异常");
//        }}/*** 连接关闭调用的方法*/@OnClosepublic void onClose(CloseReason reason) {try {webSocketSet.remove(this);  //从set中删除webSocketSet.remove(this.userId+"");  //从set中删除System.out.println("连接关闭***************"+this.userId);subOnlineCount();           //在线数减1log.info("有一连接"+this.session.getId()+"关闭!当前在线人数为" + getOnlineCount());log.info("连接"+this.session.getId()+"关闭原因:"+reason.getCloseCode()+"-"+reason.toString());}catch (Exception e){log.info("异常情况");e.printStackTrace();}}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {//{"car_dealer_id": 198,"car_resource_id": 88, "content": "H你好啊","token":"56bd2cbf1e1349f29cdbbbc54ffc1b95"}log.info("来自客户端"+session.getId()+"的消息:" + message);if(message.equals("_0_")){log.info("心跳");System.err.println("心跳");}else {Runnable t = new Runnable() {@Overridepublic void run() {JSONObject json = JSONObject.fromObject(message);AgentSendDialogueRequest asdr = (AgentSendDialogueRequest)JSONObject.toBean(json,AgentSendDialogueRequest.class);Long receiverId = 0L;Agent_Entity agent_entity = messageService.getAgentByAccessToken(asdr.getToken());if(agent_entity != null) {Long agent_id = agent_entity.getId();asdr.setFromAgentId(agent_id);receiverId = (asdr.getCar_dealer_id());//接收者idtry {if (session.isOpen()) { //先确认 session是否已经打开 使用session.isOpen() 为true 则发送消息。sendInfo(receiverId, JSONObject.fromObject(asdr).toString()); //把发送者userId的消息发给-->receiverId接收者id}} catch (EOFException e) {log.info("报错EOFException" + e.getMessage());System.err.println("报错EOFException" + e.getMessage());} catch (IOException e) {log.info("报错IOException" + e.getMessage());e.printStackTrace();}finally {//入库操作}}}};executorService.submit(t);}}/*** @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误" + error);error.printStackTrace();}public void sendMessage(String message) throws IOException {synchronized (this.session) {this.session.getBasicRemote().sendText(message);}}/*** 私发** @param message* @throws IOException*/public static void sendInfo(Long userId, String message) throws IOException {for (WebSocketController item : webSocketSet.values()) {try {if (item.userId.equals(userId)) {item.sendMessage(message);}} catch (IOException e) {continue;}}}/*** 群发自定义消息*/public static void sendInfos(String message) throws IOException {log.info(message);for (WebSocketController item : webSocketSet.values()) {try {item.sendMessage(message);} catch (IOException e) {continue;}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketController.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketController.onlineCount--;}}

三、H5客户端

1.代码实现

<!DOCTYPE html>
<html lang="en" >
<head><meta charset="UTF-8"><!--<meta name="viewport" content="width=device-width, initial-scale=1">--><title>PC端聊天窗口</title><script src="jQuery-2.1.4.min.js" type="text/javascript"></script><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600" rel="stylesheet"><link rel="stylesheet" href="webChat/css/reset.min.css"><link rel="stylesheet" href="webChat/css/style.css"></head>
<body>
<!--连接服务器-->
<div style="margin: 10px 10px;"><input type="text" placeholder="请输入账号" id="phone"  style="width: 200px;height: 30px;"/><input type="button" id="connect" value="连接服务器" style="width: 200px;height: 30px;background: #FF0B0A"/>
</div>
<div class="wrapper"><div class="container" style="width: 86%;"><div class="left" style="overflow-y: auto;overflow-x: hidden;"><div class="top" style="position: absolute;top: -3%;height: 73px;width: 37%;z-index: 999"><input type="text" placeholder="昵称、车商名、店名、店址查询" id="putSearch" style="width: 206px;padding-left: 6px" /><a href="javascript:;" class="search" onclick="select()"></a></div><ul class="people" id="chatList" style="margin-top: 18%;"></ul></div><div class="right" id="chatLog" style="overflow-y: auto;overflow-x: hidden;"><div class="top"><span>To: <span class="name">Dog Woofson</span></span></div><!--<div class="chat" data-chat="person1" >--><!--<div class="conversation-start">--><!--<span>Today, 6:48 AM</span>--><!--</div>--><!--<div class="bubble you">--><!--Hello,--><!--</div>--><!--<div class="bubble you">--><!--it's me.--><!--</div>--><!--<div class="bubble you">--><!--I was wondering...--><!--</div>--><!--</div>--><!--<div class="chat" data-chat="person2">--><!--<div class="conversation-start">--><!--<span>Today, 5:38 PM</span>--><!--</div>--><!--<div class="bubble you">--><!--Hello, can you hear me?--><!--</div>--><!--<div class="bubble you">--><!--I'm in California dreaming--><!--</div>--><!--<div class="bubble me">--><!--... about who we used to be.--><!--</div>--><!--<div class="bubble me">--><!--Are you serious?--><!--</div>--><!--<div class="bubble you">--><!--When we were younger and free...--><!--</div>--><!--<div class="bubble you">--><!--I've forgotten how it felt before--><!--</div>--><!--</div>--><!--<div class="chat" data-chat="person3">--><!--<div class="conversation-start">--><!--<span>Today, 3:38 AM</span>--><!--</div>--><!--<div class="bubble you">--><!--Hey human!--><!--</div>--><!--<div class="bubble you">--><!--Umm... Someone took a shit in the hallway.--><!--</div>--><!--<div class="bubble me">--><!--... what.--><!--</div>--><!--<div class="bubble me">--><!--Are you serious?--><!--</div>--><!--<div class="bubble you">--><!--I mean...--><!--</div>--><!--<div class="bubble you">--><!--It’s not that bad...--><!--</div>--><!--<div class="bubble you">--><!--But we’re probably gonna need a new carpet.--><!--</div>--><!--</div>--><!--<div class="chat" data-chat="person4">--><!--<div class="conversation-start">--><!--<span>Yesterday, 4:20 PM</span>--><!--</div>--><!--<div class="bubble me">--><!--Hey human!--><!--</div>--><!--<div class="bubble me">--><!--Umm... Someone took a shit in the hallway.--><!--</div>--><!--<div class="bubble you">--><!--... what.--><!--</div>--><!--<div class="bubble you">--><!--Are you serious?--><!--</div>--><!--<div class="bubble me">--><!--I mean...--><!--</div>--><!--<div class="bubble me">--><!--It’s not that bad...--><!--</div>--><!--</div>--><!--<div class="chat" data-chat="person5">--><!--<div class="conversation-start">--><!--<span>Today, 6:28 AM</span>--><!--</div>--><!--<div class="bubble you">--><!--Wasup--><!--</div>--><!--<div class="bubble you">--><!--Wasup--><!--</div>--><!--<div class="bubble you">--><!--Wasup for the third time like is <br />you blind bitch--><!--</div>--><!--</div>--><!--<div class="chat" data-chat="person6">--><!--<div class="conversation-start">--><!--<span>Monday, 1:27 PM</span>--><!--</div>--><!--<div class="bubble you">--><!--So, how's your new phone?--><!--</div>--><!--<div class="bubble you">--><!--You finally have a smartphone :D--><!--</div>--><!--<div class="bubble me">--><!--Drake?--><!--</div>--><!--<div class="bubble me">--><!--Why aren't you answering?--><!--</div>--><!--<div class="bubble you">--><!--howdoyoudoaspace--><!--</div>--><!--</div>--><div class="write"><a href="javascript:;" class="write-link attach"></a><input type="text" id="content" placeholder="请输入发送的消息" /><a href="javascript:;" class="write-link smiley"></a><a href="javascript:;" class="write-link send" id="send"></a></div></div></div>
</div><!--<script  src="webChat/js/index.js"></script>--><div style="text-align:center;margin:1px 0; font:normal 14px/24px 'MicroSoft YaHei';color: #dddddd;">
<p>适用浏览器:360、FireFox、Chrome、Opera、傲游、搜狗、世界之窗. 不支持Safari、IE8及以下浏览器。</p>
</div><script>var loginUrl = "//localhost:8080/messageController/getAgentByAccessToken_web";var token = "1";var url = "ws://localhost:8080/websocket/";var selectAllDealerUrl = "//localhost:8080/messageController/selectAllDealer";var chatLogUrl = "//localhost:8080/messageController/InformationListShowTwo";$(document).ready(function() {alert("请先在左上角输入1-180其中一个数字进行连接");});var car_dealer_id_send = "";var oPhone = document.getElementById('phone');var oUl=document.getElementById('content');var oConnect=document.getElementById('connect');var oSend=document.getElementById('send');var oInput=document.getElementById('message');var chatList=document.getElementById('chatList');var chatLog=document.getElementById('chatLog');var ws=null;var agentId = null;var agentType = null;oConnect.onclick=function(){console.log("oPhone="+oPhone.value);if(oPhone.value==""){alert("请先在左上角输入1-180其中一个数字进行连接");return;}//登陆//把聊天列表列表查询出来$.ajax({url:loginUrl,    //请求的url地址contentType: "application/json",dataType:"json",   //返回格式为jsonasync:true,//请求是否异步,默认为异步,这也是ajax重要特性data:{"token":oPhone.value},    //参数值type:"GET",   //请求方式// headers:{"token":token},beforeSend:function(){//请求前的处理chatList.innerHTML += "<h2 class='time' style='font-size: 18px;color:red;'>正在加载聊天列表中...请稍等</h2>";},success:function(data){//请求成功时处理console.log(data.data);if(data.result == "success"){console.log("登陆agent_id="+data.data.agentId+"--nickName="+data.data.nickName+"--name身份="+data.data.contact);agentId = data.data.agentId;//连接webScoket   startws=new WebSocket(url+agentId);ws.onopen=function(){oConnect.value = data.data.nickName+"-已连接服务器";token = oPhone.value;console.log(oPhone.value+"连接成功--token="+token+"--连接地址="+(url+agentId));//把聊天列表查询出来selectChatList("");}ws.onmessage=function(result){var jsons = JSON.parse(result.data);console.log("服务器发送的数据="+result.data+"--jsons.content="+jsons.content+"--jsons.fromAgentId="+jsons.fromAgentId);//如果处于当前聊天对象窗口-直接添加新消息到聊天记录if(car_dealer_id_send == jsons.fromAgentId){chatLog.innerHTML += "<div class='bubble you'>"+jsons.content+"</div>";//划到最底部chatLog.scrollTop = chatLog.scrollHeight; //滚动到最下面}else{//如果未处于当前聊天对象窗口-添加红点样式$('#id'+jsons.fromAgentId).addClass("search");document.getElementById('id'+jsons.fromAgentId).class="search";}}ws.onclose=function(){oUl.innerHTML+="<li>客户端已断开连接</li>";};ws.onerror=function(evt){console.log("onerror了,重连地址="+url+agentId);ws=new WebSocket(url+agentId);};//开启心跳 + 断线重联setInt;//连接webSocket   end}else{alert("登陆失败,请重新连接");}},complete:function(){//请求完成的处理},error:function(){//请求出错处理}});};function selectChatList(putSearch) {//把聊天列表列表查询出来$.ajax({url:selectAllDealerUrl,    //请求的url地址contentType: "application/json",dataType:"json",   //返回格式为jsonasync:true,//请求是否异步,默认为异步,这也是ajax重要特性data:{"select":putSearch},    //参数值type:"GET",   //请求方式// headers:{"token":token},beforeSend:function(){//请求前的处理chatList.innerHTML="";chatList.innerHTML += "<h2 class='time' style='font-size: 18px;color:red;'>正在加载聊天列表中...请稍等</h2>";},success:function(data){//请求成功时处理chatList.innerHTML="";console.log(data.data);if(data.result == "success"){$.each(data.data,function(i,value){if(value.notify_type=="MESSAGE"){console.log(i+"--"+value.notify_type+"--"+value.car_dealer_id);chatList.innerHTML +=// "<li class='person' data-chat='person"+i+"' onclick='inTwo("+value.car_dealer_id+")'>"+"<li class='person' data-chat='person"+i+"'  onclick=\"inTwo(" + value.car_dealer_id + ",'" + value.shop_name + "');\"  >"+"<a class='a' id='id"+value.car_dealer_id+"' style='background-color:red;width: 10px;height: 10px;color: #FF0B0A;'></a>"+"<img src='webChat/img/thomas.jpg' alt='' />"+"<span class='name'>"+value.shop_name+"</span>"+"<span class='time'>"+value.sender_type+"</span>"+// "<span class='preview'>"+value.car_dealer_id+"</span>"+"</li>";}})}else{alert("聊天列表加载失败");}},complete:function(){//请求完成的处理},error:function(){//请求出错处理}});}function inTwo(car_dealer_id,shop_name) {car_dealer_id_send = car_dealer_id;console.log("car_dealer_id===="+car_dealer_id+"--shop_name="+shop_name);//去除红点$('#id'+car_dealer_id).removeClass("search");//把聊天记录查询出来$.ajax({url:chatLogUrl,    //请求的url地址contentType: "application/json",dataType:"json",   //返回格式为jsonasync:true,//请求是否异步,默认为异步,这也是ajax重要特性data:{"notify_type":"MESSAGE","car_dealer_id":car_dealer_id},    //参数值type:"GET",   //请求方式headers:{"token":token},beforeSend:function(){//请求前的处理chatLog.innerHTML += "<h1 class='time' style='position:fixed;top:-87px;z-index:999;font-size: 22px;color:red;'>正在加载聊天记录中...请稍等</h1>";},success:function(data){//请求成功时处理chatLog.innerHTML ="";// console.log(data.data.messageModels);if(data.result == "success"){chatLog.innerHTML ="<div class='top' style='position:fixed;top:-47px;z-index:999;width: 62.4%;'><span>正再与: <span class='name' style='color: #FF0B0A;'>"+shop_name+"</span> 聊天</span></div>";$.each(data.data.messageModels,function(i,value){// console.log("消息内容="+value.content);// chatLog.innerHTML += "<div class='bubble you'>"+value.content+"</div>";if(value.sender_type == "DEALER"){chatLog.innerHTML += "<div class='bubble you'>"+value.content+"--"+value.created_at+"</div>";}if(value.sender_type=="AGENT"){chatLog.innerHTML += "<div class='bubble me'>"+value.content+"--"+value.created_at+"</div>";}})chatLog.scrollTop = chatLog.scrollHeight; //滚动到最下面chatLog.innerHTML +="<div class='write' style='position:fixed;bottom:-7%;left: 42%;width: 52%;'>"+"<a href='javascript:;' class='write-link attach'></a>"+"<input type='text' id='content' placeholder='请输入发送的消息' style='background: #eb7350;' />"+// "<a href='javascript:;' class='write-link smiley'></a>"+"<a href='javascript:;' class='write-link send' id='send' onclick='sendOn(car_dealer_id_send)'></a>"+"</div>";}else{alert("聊天记录加载失败");}},complete:function(){//请求完成的处理},error:function(){//请求出错处理}});}function sendOn(car_dealer_id){console.log("sendOn接收者id="+car_dealer_id);var json={"car_dealer_id": car_dealer_id,"car_resource_id": 1,"content": $("#content").val(),"token":token};console.log("点击了发送数据="+$("#content").val()+"---"+oUl.value);if(ws){ws.send(JSON.stringify(json));chatLog.innerHTML += "<div class='bubble me'>"+$("#content").val()+"</div>";chatLog.scrollTop = chatLog.scrollHeight; //滚动到最下面}}//心跳 + 断线重连var times= 1000*50;var setInt=setInterval(function heartbeat(){if(ws.readyState==1){ // 0=正在连接  1=表示连接成功,可以通信了ws.send('_0_');console.log("心跳发送"+ws+"(每"+(times/1000)+"秒一次)");times = 1000*50;}else if(ws.readyState==3){  // 2=连接正在关闭   3=连接已经关闭,或者打开连接失败。times = 2000;console.log("断线重连url="+url+agentId+"(每"+(times/1000)+"秒一次)      heartbeat"+ws);ws = new WebSocket(url+agentId);}},times);//搜索function select() {var putSearch = document.getElementById('putSearch');console.log(putSearch.value);selectChatList(putSearch.value);$("#putSearch").val(""); //设置搜索框的值为空}
</script></body>
</html>

HTML、css、js资料下载地址

链接:https://pan.baidu.com/s/1VXYBiz5vKrMmlvWpqYw-4A 
提取码:2xtq

开发过程如有疑问可交流讨论 WX:18637815946

SpringBoot应用WebSocket实现在线聊天相关推荐

  1. SpringBoot与webSocket实现在线聊天室——实现私聊+群聊+聊天记录保存

    SpringBoot与webSocket实现在线聊天室--实现私聊+群聊+聊天记录保存 引用参考:原文章地址:https://blog.csdn.net/qq_41463655/article/det ...

  2. springboot -- 整合websocket 实现在线聊天

    项目demo: 链接:https://pan.baidu.com/s/1xZtU-Rqc58m0-v397OW3hQ 提取码:01pt 复制这段内容后打开百度网盘手机App,操作更方便哦 websoc ...

  3. SpringBoot 使用WebSocket打造在线聊天室(基于注解)

    点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 精彩内容 java实战练习项目教程 2018微服务资源springboot.s ...

  4. SpringBoot集成WebSocket实现在线聊天

    文章目录 前言 1.WebSocket引入 2.环境搭配 2.1.工程创建 2.2.依赖导入 2.3.配置类 3.具体实现 3.1.前置知识 3.2.数据封装 3.3.思路分析 3.4.服务构建 3. ...

  5. Springboot + WebSocket 实现在线聊天

    一.后端 1.在Springboot项目的pom.xml中添加依赖 <!--websocket协议--> <dependency><groupId>org.spri ...

  6. springboot+websocket构建在线聊天室(群聊+单聊)

    系列导读: 1.springboot+websocket构建在线聊天室(群聊+单聊) 2.Spring Boot WebSocket:单聊(实现思路) 3.Websocket Stomp+Rabbit ...

  7. 【SpringBoot框架篇】18.使用Netty加websocket实现在线聊天功能

    文章目录 1.简介 2.最终功能实现的效果图 2.1.pc端 2.2.移动端 3.实战应用 3.1.引入依赖 3.2.配置文件 3.3.测试demo 3.3.1.消息内容实体类 3.3.2.处理请求的 ...

  8. SpringBoot基于websocket的网页聊天

    一.入门简介 正常聊天程序需要使用消息组件ActiveMQ或者Kafka等,这里是一个Websocket入门程序. 有人有疑问这个技术有什么作用,为什么要有它? 其实我们虽然有http协议,但是它有一 ...

  9. WebSocket实现在线聊天

    WebSocket实现在线聊天 前两天在公司接到一个需求,使用WebSocket实现微信扫码登陆,当时了解了一下WebSocket,都说WebSocket可以实现在线聊天,所以我自己也写了一个.(发个 ...

最新文章

  1. ASP.Net4.0中新增23项功能
  2. linux定时任务配置失效,linux下定时任务和延迟任务
  3. VTK修炼之道41:频域处理_低通滤波(理想+巴特沃兹)
  4. python中head_Python pandas.DataFrame.head函数方法的使用
  5. ActiveMQ的消息存储(八)
  6. ubuntu 21.04 版本上 安装 sqlcmd
  7. 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第2节 TCP协议_1_TCP通信的概述(上)...
  8. 交互设计之层次设计配色篇(表达逻辑——前进色与后退色)
  9. 小学生python编程教程-画正方形-小学生 Python 入门课
  10. 不用U盘,给自己的电脑重装一个win10系统
  11. 苹果MFI认证步骤汇总
  12. Java 中的Date(获取一天的开始时间和结束时间)
  13. java生成word,html文件并将内容保存至数据库 (http://blog.163.com/whs3727@126/blog/static/729915772007325112014115/)
  14. java利用zxing生成二维码
  15. 【SayGoodBye.java】一封离职告别信
  16. JavaSE基础知识(附上代码实现)1
  17. 用matlab编写了一个DSP数据处理小软件
  18. 大红喜庆版UI猜灯谜又叫猜字谜微信小程序源码下载
  19. vb中的clng函数
  20. Matlab播放音频文件(音乐)!

热门文章

  1. threejs旋转模型动画教程
  2. 数据库查询+数据库备份+数据库恢复
  3. 【高德LBS开源组件大赛】地震来了
  4. macbook 终端命令怎么使用_玩转 Terminal 终端:入门指南及进阶技巧
  5. python line strip_关于python 的line.strip()方法
  6. 高度设置php,uedit设置固定高度
  7. Git——git的简单使用以及连接gitee的远程仓库[经验 y.2]
  8. apriori java_频繁模式挖掘apriori算法介绍及Java实现
  9. selenium切换iframe框架案例——翻页爬取网易云音乐歌单作者和名称
  10. 《开源软件架构》--nginx配置与内部(三)