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

25转行做网站运营兰州网络推广公司哪家好

25转行做网站运营,兰州网络推广公司哪家好,小说网站开发的看书软件,网站维护外包方案一、界面展示 二、前置了解 1.什么是websocket WebSocket是一种在单个TCP连接上进行全双工通信的持久化协议。 全双工协议就是客户端可以给我们服务器发数据 服务器也可以主动给客户端发数据。 2.为什么有了http协议 还要websocket 协议 http协议是一种无状态,非…

一、界面展示

二、前置了解

1.什么是websocket

WebSocket是一种在单个TCP连接上进行全双工通信的持久化协议。
全双工协议就是客户端可以给我们服务器发数据 服务器也可以主动给客户端发数据。

2.为什么有了http协议 还要websocket 协议

http协议是一种无状态,非持久化的单全双工应用层协议。
主要用于一问一答的方式交付信息,即客户端发送请求,服务器返回响应。这种模式适合于获取数据或者提交数据的场景。

所以http协议中,服务器无法主动给客户端发送数据,导致出现服务器数据状态发生改变,客户端无法感知。

针对上面的问题,http 勉强可以通过 定时轮询 和 长轮询 解决问题。

定时轮询:客户端不断地定时请求服务器, 询问数据状态变更的情况。
定时轮询的弊端:存在延时,浪费服务器资源和带宽,存在大量无效请求。

长轮询:拉长请求时间,客户端发送请求后,服务器在没有新数据时不会立即响应,而是等到有新数据时才返回响应。这种方法可以减少无效的请求,
长轮询的弊端:仍然需要频繁地建立和断开连接,且服务器需要维护未完成的请求,这可能会占用大量的服务器资源。

承上启下 所有最后我们websocket应运而生,它就是为了解决这个问题而设计的。
WebSocket协议可以实现全双工通信,即客户端和服务器可以在任何时候 相互 主动发送数据。此外,一旦WebSocket连接建立,客户端和服务器之间的连接将保持活动状态,直到被任何一方关闭。

三、附集成代码

1.引入pom依赖
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
2.使用@ServerEndpoint创建WebSocket Endpoint
package com.ruoyi.framework.websocket;import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.WebSocketConfig;
import com.ruoyi.framework.web.service.TokenService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;import org.slf4j.LoggerFactory;/*** @author qujingye* @Classname WebSocketServer* @Description  虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean* @Date 2023/12/19 16:11*/
@Component
@ServerEndpoint(value = "/websocket/message", configurator = WebSocketConfig.class)
public class WebSocketServer {private static TokenService tokenService;@Autowiredprivate void setOriginMessageSender(TokenService tokenService) {WebSocketServer.tokenService = tokenService;}/*** WebSocketServer 日志控制器*/private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);private final static ConcurrentHashMap<Long, CopyOnWriteArrayList<Session>> sessionPool = new ConcurrentHashMap<>();private final static AtomicLong atomicLong = new AtomicLong(0L);/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session) throws Exception {Long userId = parseUserId(session);System.out.println(userId);LOGGER.info("[WebSocket] 有新的连接, 当前用户id: {}", userId);if (userId == null) {return;}CopyOnWriteArrayList<Session> sessions = sessionPool.get(userId);//不存在其他人登陆if (null == sessions) {sessions = new CopyOnWriteArrayList<>();}sessions.add(session);sessionPool.put(userId, sessions);atomicLong.getAndIncrement();LOGGER.info("[WebSocket] 有新的连接, 当前连接数: {}", atomicLong.get());}/*** 连接关闭时处理*/@OnClosepublic void onClose(Session session) {Long userId = parseUserId(session);if (userId == null) {return;}CopyOnWriteArrayList<Session> sessions = sessionPool.remove(userId);CopyOnWriteArrayList<Session> newSessions = new CopyOnWriteArrayList<>();for (Session s : sessions) {if (!s.getId().equals(session.getId())) {newSessions.add(s);}}sessionPool.put(userId, newSessions);atomicLong.getAndDecrement();LOGGER.info("[WebSocket] 连接断开, 当前连接数: {}", atomicLong.get());}/*** 抛出异常时处理*/@OnErrorpublic void onError(Session session, Throwable exception) throws Exception {LOGGER.error("用户错误:,原因:" + exception.getMessage());}/*** 服务器接收到客户端消息时调用的方法*/@OnMessagepublic void onMessage(String message, Session session) {//把收到的消息发回去session.getAsyncRemote().sendText(message);LOGGER.info("message: {}", message);}/*** 给该用户id的全部发送消息*/public void sendMessage(Long userId, String message) {CopyOnWriteArrayList<Session> sessions = sessionPool.get(userId);if (null == sessions || sessions.size() == 0) {return;}sessions.forEach(s -> s.getAsyncRemote().sendText(message));}/*** 获取用户id*/private Long parseUserId(Session session) {String token = (String) session.getUserProperties().get(WebSocketConfig.WEBSOCKET_PROTOCOL);if (StringUtils.isNotEmpty(token)) {LoginUser loginUser = tokenService.getLoginUserByToken(token);if (loginUser != null) {return loginUser.getUserId();}}return null;}
}
3.定义WebSocketConfig

注入ServerEndpointExporter来自动注册端点

package com.ruoyi.framework.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import java.util.List;
import java.util.Map;/*** @author qujingye* @Classname WebSocketConfig* @Description 继承服务器断点配置类* @Date 2023/12/19 16:08*/
@Configuration
public class WebSocketConfig extends ServerEndpointConfig.Configurator {/*** WebSocket的协议头*/public final static String WEBSOCKET_PROTOCOL = "Sec-Websocket-Protocol";/*** 注入ServerEndpointExporter,这个Bean会自动注册使用了@ServerEndpoint注解声明的WebSocket Endpoint。*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}/*** 建立握手时,连接前的操作*/@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {// 这个用户属性userProperties 可以通过 session.getUserProperties()获取final Map<String, Object> userProperties = sec.getUserProperties();Map<String, List<String>> headers = request.getHeaders();List<String> protocol = headers.get(WEBSOCKET_PROTOCOL);// 存放自己想要的header信息if (protocol != null) {userProperties.put(WEBSOCKET_PROTOCOL, protocol.get(0));}}/*** 创建端点实例,也就是被@ServerEndpoint所标注的对象*/@Overridepublic <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {return super.getEndpointInstance(clazz);}}
4.定义过滤器设置响应头
package com.ruoyi.framework.security.filter;import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.config.WebSocketConfig;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** FileName:     com.admin.security.filter WebsocketFilter* Date:         2023/8/1 16:42** @author Messylee*/
@Order(1)
@Component
@WebFilter(filterName = "WebsocketFilter", urlPatterns = "/ws/**")
public class WebsocketFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) servletResponse;HttpServletRequest headers = (HttpServletRequest) servletRequest;String token = headers.getHeader(WebSocketConfig.WEBSOCKET_PROTOCOL);if (StringUtils.isNotEmpty(token)){response.setHeader(WebSocketConfig.WEBSOCKET_PROTOCOL, token);}filterChain.doFilter(servletRequest, servletResponse);}}
5.vue前端界面代码

<template><div class="app-container home"><el-row :gutter="20"><el-col :sm="24" :lg="24"><h1>集成websocket测试</h1></el-col></el-row><el-row :gutter="20"><el-col :sm="24" :lg="24"><div><el-input v-model="url" type="text" style="width: 20%" /> &nbsp;&nbsp;<el-button @click="join" type="primary">连接</el-button><el-button @click="exit" type="danger">断开</el-button><el-button @click="resetForm" type="success">重置</el-button><br /><br /><el-input type="textarea" v-model="message" :rows="9" /><br /><br /><el-button type="success" @click="send">发送消息</el-button><br /><br />返回内容<el-input type="textarea" v-model="text_content" :rows="9" /><br /><br /></div></el-col></el-row></div>
</template><script>
import { getToken } from "@/utils/auth";export default {name: "Index",data() {return {url: "ws://127.0.0.1:8080/websocket/message",message: "",text_content: "",ws: null,headers: {Authorization: "Bearer " + getToken(),},};},methods: {join() {const wsuri = this.url;// this.ws = new WebSocket(wsuri);this.ws = new WebSocket(wsuri, [getToken()]);const self = this;// 连接成功后调用this.ws.onopen = function (event) {self.text_content = self.text_content + "WebSocket连接成功!" + "\n";};this.ws.onerror = function (event) {self.text_content = self.text_content + "WebSocket连接发生错误!" + "\n";};// 接收后端消息this.ws.onmessage = function (event) {self.text_content = self.text_content + event.data + "\n";};// 关闭连接时调用this.ws.onclose = function (event) {self.text_content = self.text_content + "已经关闭连接!" + "\n";};},exit() {if (this.ws) {this.ws.close();this.ws = null;}},send() {if (this.ws) {this.ws.send(this.message);} else {alert("未连接到服务器");}},//重置resetForm() {this.message = "";this.text_content = "";},},
};
</script>

http://www.ds6.com.cn/news/76290.html

相关文章:

  • 有没有什么东西可以做网站安徽网站优化
  • 深圳企业网站建设定制开发服务怎样做自己的网站
  • 中小型企业网络建设宁波谷歌seo
  • 广告公司网站建设的定位baidu 百度一下
  • 做网站公司好网站如何快速收录
  • 水头网站建设百度客户服务电话是多少
  • 网站设计佛山顺德googleplay官方下载
  • 怎样建免费网站sem推广是什么
  • 贸易公司自建免费网站品牌推广网络公司
  • wordpress 下拉刷新广州做seo公司
  • 国内做网站最大的公司今天最新新闻国内大事件
  • 机关网站建设制度企业培训系统app
  • 做自己的程序设计在线测评网站广州市口碑全网推广报价
  • 动态网站开发报告宁波关键词优化平台
  • 龙岗网站设计讯息第一推广网
  • 北京创意设计协会网站电商网站策划
  • 沈阳做网站的公司排名新手如何涨1000粉
  • 响应式网站建设对企业营销广州疫情最新消息
  • 专业做财务公司网站百度快照客服
  • 南宁网站开发企业精准营销系统
  • 12网站免费建站珠海百度搜索排名优化
  • wordpress 删除emjo上海搜索排名优化
  • 重庆红旗河沟网站建设国家市场监督管理总局官网
  • 漯河哪里做网站软文优化
  • 网站通栏广告代码三只松鼠网络营销案例分析
  • app开发专业公司2022年seo最新优化策略
  • 做零食网站的选题理由手机建站系统
  • 社区居委会网站建设国内最新十大新闻
  • 网站建设 中企动力板材生态板快速提升网站排名
  • 做网站和做微信小程序网络营销运营方案