一.HTTP
说到websocket首先要说Http,Http大家都知道是一个网络通信协议,每当客户端浏览器需要访问后台时都会发一个请求,服务器给出响应后该连接就会关闭,请求只能有客户端发起,服务端是没办法主动发起请求的,对于消息推送的需求Http也可以满足要求,就是前端采用定时任务的方式去请求接口,这种轮询的方式是非常损耗服务器性能的,要尽量避免。基于此产生了全双工的网络协议-websocket。
二.WebSocket
所谓全双工指的是通信可以由任意一方发起,可以在两个方向上传输信息,采用websocket可以很好的实现消息推送的功能,从而避免了轮询的方式导致资源浪费的问题。
三.实现方式
这里采用springboot集成websocket,在springboot中使用websocket非常的方便。
首先导入websocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
在启动类上添加一个bean
@SpringBootApplication
public class CommonCodeApplication {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
public static void main(String[] args) {
SpringApplication.run(CommonCodeApplication.class, args);
}
}
核心代码
@Component
@ServerEndpoint("/websocket2/{username}")
@Slf4j
public class WebSocketDemo2 {
private static Map<String, WebSocketDemo2> webSocketMap = new HashMap<>();
private static Integer onlineUserCount = 0;
private Session session;
private String username;
/**
* 建立连接
* @param username
* @param session
*/
@OnOpen
public void onOpen(@PathParam("username") String username, Session session){
this.username = username;
this.session = session;
webSocketMap.put(username, this);
int count = addOnlineUser();
log.info("当前在线用户:" + count);
}
/**
* 关闭连接
* @param username
*/
@OnClose
public void onClose(@PathParam("username") String username){
webSocketMap.remove(username);
int count = reduceOnlineUser();
log.info("当前在线用户:" + count);
}
@OnMessage
public void onMessage(String message) throws IOException {
JSONObject jsonObject = JSONUtil.parseObj(message);
String target = jsonObject.getStr("target");
String msg = jsonObject.getStr("msg");
if (target.equals("all")){
sendMessageAll(msg);
}
}
/**
* 给特定的人发消息,用于业务中调用
* @param usernames
* @param message
* @throws IOException
*/
public void sendMessageSpecial(List<String> usernames, String message) throws IOException {
for (String username : webSocketMap.keySet()) {
for (String target : usernames) {
if (username.equals(target)){
webSocketMap.get(username).session.getBasicRemote().sendText(message);
}
}
}
}
/**
* 给所有人发消息
* @param message
* @throws IOException
*/
public void sendMessageAll(String message) throws IOException {
for (WebSocketDemo2 item : webSocketMap.values()) {
System.out.println("消息发送");
item.session.getBasicRemote().sendText(message);
}
}
public void sendMessage(String message) throws IOException {
session.getBasicRemote().sendText(message);
}
/**
* 用户离线
* @return
*/
public int reduceOnlineUser(){
return -- onlineUserCount;
}
/**
* 累加在线用户
* @return
*/
public int addOnlineUser(){
return ++ onlineUserCount;
}
}
实现消息推送只要在业务代码中调用sendMessageSpecial()方法即可。
@RestController
@RequestMapping("/websocket")
public class WebSocketController {
@Autowired
private WebSocketDemo2 webSocketDemo2;
@GetMapping("/t1")
public String test1() throws IOException {
System.out.println("这是业务代码...");
String message = "消息被督办了!";
List<String> usernames = new ArrayList<>();
usernames.add("张三");
usernames.add("李四");
usernames.add("王五");
webSocketDemo2.sendMessageSpecial(usernames, message);
return "ok";
}
}
四.测试
这里不用写前端去测试,大家可以使用这个网站进行测试
websocket测试
这里开了三个窗口进行测试,三个人的姓名分别是:张三、李四、王五
然后调用刚才的业务接口测试:http://localhost:8080/websocket/t1
调用成功后可以看到三个窗口中都收到了消息

我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
我一直很高兴地使用DelayedJob习惯用法:foo.send_later(:bar)这会调用DelayedJob进程中对象foo的方法bar。我一直在使用DaemonSpawn在我的服务器上启动DelayedJob进程。但是...如果foo抛出异常,Hoptoad不会捕获它。这是任何这些包中的错误...还是我需要更改某些配置...或者我是否需要在DS或DJ中插入一些异常处理来调用Hoptoad通知程序?回应下面的第一条评论。classDelayedJobWorker 最佳答案 尝试monkeypatchingDelayed::W
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas
我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=
我正在使用Ruby,我正在与一个网络端点通信,该端点在发送消息本身之前需要格式化“header”。header中的第一个字段必须是消息长度,它被定义为网络字节顺序中的2二进制字节消息长度。比如我的消息长度是1024。如何将1024表示为二进制双字节? 最佳答案 Ruby(以及Perl和Python等)中字节整理的标准工具是pack和unpack。ruby的packisinArray.您的长度应该是两个字节长,并且按网络字节顺序排列,这听起来像是n格式说明符的工作:n|Integer|16-bitunsigned,network(bi
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o