首页
赞助
时间轴
追番
留言
友人帐
关于
个人导航
更多
学习笔记
壁纸
Search
1
【台式机】2020-06-07,上半年618推荐配置(都是AMD)
953 阅读
2
21年下半年笔记本挑选
918 阅读
3
域名备案成功
789 阅读
4
2020.10 手机号码正则表达式
730 阅读
5
Mybatis缓存
696 阅读
日常
代码
❤心情
博客插件
电脑推荐
KMS服务
登录
Search
标签搜索
电脑推荐
组装电脑
博客插件
跨域访问错误
Maven
Mybatis
node.js
WebSocket
SpringBoot
Linux
跨域
网页背景效果
音乐播放器
看板娘
Pio插件问题
气泡通知
轻薄本
全能本
笔记本推荐
伪静态
旧梦未眠
累计撰写
71
篇文章
累计收到
13
条评论
今日撰写
0
篇文章
首页
栏目
日常
代码
❤心情
博客插件
电脑推荐
KMS服务
页面
赞助
时间轴
追番
留言
友人帐
关于
个人导航
学习笔记
壁纸
用户登录
登录
搜索到
71
篇与
的结果
2020-09-28
time.windows.com无法同步时间
ping time.windows.com如果被墙无法访问,手动更换时间服务器。步骤:控制面板-时钟和区域-日期和时间-Internet时间-更改设置地址:ntp.ntsc.ac.cn
2020年09月28日
322 阅读
0 评论
0 点赞
2020-09-10
Nginx开启WebSocket
#开启WebSocket proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; #设置连接时间 proxy_read_timeout 600s;如果想长时间在线需要js发送心跳包,可以看看SSM整合WebSocket 也就是上一篇文章,最后放出了JavaScript的心跳代码。
2020年09月10日
316 阅读
0 评论
0 点赞
2020-09-10
SSM整合WebSocket
1、首先导包<!--websocket--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>5.2.6.RELEASE</version> </dependency>2、WebSocketConfig.javaimport org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; import org.springframework.web.socket.handler.TextWebSocketHandler; @Configuration @EnableWebMvc//这个标注可以不加,如果有加,要extends WebMvcConfigurerAdapter @EnableWebSocket public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { //1.注册WebSocket String websocket_url = "/websocket/socketServer"; //设置websocket的地址 registry.addHandler(webSocketHandler(), websocket_url). //注册Handler addInterceptors(new WebSocketHandshakeInterceptor()); //注册Interceptor //2.注册SockJS,提供SockJS支持(主要是兼容ie8) String sockjs_url = "/sockjs/socketServer"; //设置sockjs的地址 registry.addHandler(webSocketHandler(), sockjs_url). //注册Handler addInterceptors(new WebSocketHandshakeInterceptor()). //注册Interceptor withSockJS(); //支持sockjs协议 } @Bean public TextWebSocketHandler webSocketHandler() { return new WebSocketHandler(); } }3、WebSocketHandler.javaimport com.jam.pojo.WebSocketUser; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class WebSocketHandler extends TextWebSocketHandler { // 已建立连接的用户 private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>(); SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss"); /** * 处理前端发送的文本信息 js调用websocket.send时候,会调用该方法 * * @param session * @param message * @throws Exception */ @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME"); // 获取提交过来的消息详情 System.out.println("收到用户 " + username + " 的消息:" + message.toString()); // 分割成id和信息内容 String[] messageInfo = message.getPayload().split("@"); if (messageInfo.length != 2) { } else { String target = messageInfo[0]; String content = messageInfo[1]; // 遍历所有已连接用户 for (WebSocketSession user : users) { if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(target)) { //遇到匹配用户 连接正常则发送消息 if (user.isOpen()) { sendMessageToUser(target, new TextMessage("来自\""+username+"\"的消息:"+content+"----"+sdf.format(new Date()))); }else{//若异常则发送失败 sendMessageToUser(username, new TextMessage("对方在线异常,发送失败"+"----"+sdf.format(new Date()))); } return; } } //未找到匹配用户 发送失败 sendMessageToUser(username, new TextMessage("对方暂时不在线"+"----"+sdf.format(new Date()))); } } /** * 当新连接建立的时候,被调用 连接成功时候,会触发页面上onOpen方法 * * @param session * @throws Exception */ @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { users.add(session); String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME"); System.out.println("用户 " + username + " Connection Established"); session.sendMessage(new TextMessage(username + " connect")); } /** * 当连接关闭时被调用 * * @param session * @param status * @throws Exception */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME"); System.out.println("用户 " + username + " Connection closed. Status: " + status); users.remove(session); } /** * 传输错误时调用 * * @param session * @param exception * @throws Exception */ @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME"); if (session.isOpen()) { session.close(); } System.out.println("用户: " + username + " websocket connection closed......"); users.remove(session); } /** * 给所有在线用户发送消息 * * @param message */ public void sendMessageToUsers(TextMessage message) { for (WebSocketSession user : users) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } } } /** * 在线用户数 * */ public List<WebSocketUser> onlineUsers() { List<WebSocketUser> userList = new ArrayList<WebSocketUser>(); for (WebSocketSession user : users) { String username = (String) user.getAttributes().get("WEBSOCKET_USERNAME"); userList.add(new WebSocketUser(username)); } return userList; } /** * 给某个用户发送消息 * * @param userName * @param message */ public void sendMessageToUser(String userName, TextMessage message) { for (WebSocketSession user : users) { if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } break; } } } }4、WebSocketHandshakeInterceptor.javaimport org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; import javax.servlet.http.HttpSession; import java.util.Map; public class WebSocketHandshakeInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false); if (session != null) { String userName = (String) session.getAttribute("SESSION_USERNAME"); //这边获得登录时设置的唯一用户标识 if (userName == null) { userName = "未知" + session.getId(); } attributes.put("WEBSOCKET_USERNAME", userName); //将用户标识放入参数列表后,下一步的websocket处理器可以读取这里面的数据 } } return true; } public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { System.out.println("After Handshake"); } }5、WebSocketController.javaimport com.alibaba.fastjson.JSON; import com.jam.pojo.WebSocketUser; import com.jam.utils.Retmsg; import com.jam.websocket.WebSocketHandler; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.socket.TextMessage; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @RestController @RequestMapping(value="/websocket",produces = "application/json; charset=utf-8") public class WebSocketController { @Bean // 这个注解会从Spring容器拿出Bean public WebSocketHandler infoHandler() { return new WebSocketHandler(); } WebSocketHandler ws = new WebSocketHandler(); SimpleDateFormat sdf = new SimpleDateFormat("MM/dd HH:mm:ss"); //登录WebSocket保存用户名 @RequestMapping("/login") public String login(String username,HttpServletRequest request) throws Exception { System.out.println(username + "登录"); HttpSession session = request.getSession(); session.setAttribute("SESSION_USERNAME", username); return Retmsg.toJsonMsg("登录成功"); } //推送给所有用户的后台接口 @RequestMapping("/sendMsgToAllUsers") public String sendMsgToAllUsers(String username,String str){ String date = sdf.format(new Date()); str+="----"+date+"[来自 \""+username+"\" 的群发信息]"; ws.sendMessageToUsers(new TextMessage(str)); return Retmsg.toJsonMsg("发送成功"); } //获取当前在线用户名 @RequestMapping("/onlineUsers") public @ResponseBody String onlineUsers(){ List<WebSocketUser> users = ws.onlineUsers(); return JSON.toJSONString(users); } }5、JavaScript+心跳包发送<script type="text/javascript"> var websocket = null; var url = window.location.host; var url2 = window.location.href; var username = url2.split("=")[1]; var website = "http://"+url+"/websocket/sendMsgToAllUsers"; if ('WebSocket' in window) { //Websocket的连接 websocket = new WebSocket("ws://"+url+"/websocket/socketServer");//WebSocket对应的地址 } else if ('MozWebSocket' in window) { //Websocket的连接 websocket = new MozWebSocket("ws://"+url+"/websocket/socketServer");//SockJS对应的地址 } else { //SockJS的连接 websocket = new SockJS("http://"+url+"/sockjs/socketServer"); //SockJS对应的地址 } websocket.onopen = onOpen; websocket.onmessage = onMessage; websocket.onerror = onError; websocket.onclose = onClose; function onOpen(openEvt) { //alert(openEvt.Data); heartCheck.reset().start(); } function onMessage(evt) { $("#content").append(evt.data+"<br>"); // 接收后台发送的数据 heartCheck.reset().start(); } function onError() { } function onClose() { } //给指定用户发消息 function doSend() { if (websocket.readyState == websocket.OPEN) { websocket.send($("#targetName").val()+"@"+$("#inputMsg").val());//调用后台handleTextMessage方法 alert("发送成功!"); } else { alert("连接失败!"+websocket.readyState); } } //给所有用户发消息 function doSend2(){ if (websocket.readyState == websocket.OPEN) { $.get(website,{username:username,str:$("#inputMsg2").val()}); alert("发送成功!"); } else { alert("连接失败!"+websocket.readyState); } } window.close = function () { websocket.onclose(); } var heartCheck = { timeout: 55000, // 9分钟发一次心跳,比server端设置的连接时间稍微小一点,在接近断开的情况下以通信的方式去重置连接时间。 serverTimeoutObj: null, reset: function(){ clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, start: function(){ var self = this; this.serverTimeoutObj = setInterval(function(){ if(websocket.readyState == 1){ console.log("连接状态,发送消息保持连接"); websocket.send("heartCheck"); heartCheck.reset().start(); // 如果获取到消息,说明连接是正常的,重置心跳检测 }else{ console.log("断开状态,尝试重连"); new WebSocket("ws://"+url+"/websocket/socketServer"); } }, this.timeout) } } </script>
2020年09月10日
303 阅读
0 评论
0 点赞
2020-08-14
下半年装机分析+机械硬盘垂直/叠瓦详细
CPURyzen 4000系列下半年铺货开始,Intel11代明年才有,下半年AMD独大,涨价开始了。中端i5 10400可能比R5 3600香了,还送核显,需要配电脑的话可能越等越香。同时10月份还有RTX30系列,按照2060s超过1080的水平,3060可能可以摸到2070s的水平(可能)。3070可能比2080好一点。如果不是很急,完全不推荐现在配游戏机,老年办公其实无所谓i3 10100,i5 10400或者是R3 4350G,R5 4650G方案都可以。笔记本但对于游戏本来说,R7000系列yyds,高端系列推荐Rog幻14,冰锐2,当然买Rog,华硕全系列,到手推荐自己换个好一点的固态,PM981A或者sn750(也就是西数黑盘)。轻薄本还是联想小新AMD系列可以看,pro13,air14,15。还有个yoga14s。小新AMD系列到手建议自行更换AX200网卡。没有动手能力网上买好网卡然后去官方服务店免费换。固态对于固态来说,推荐还是买原厂为主,高端目前PM981A和西数黑盘sn750还有铠侠RD10,中端西数蓝盘sn550和铠侠RC10,入门金士顿A2000。SATA的话西数蓝盘,铠侠TC10都可以。性价比倒是考虑下西数绿盘,科赋固态不用了,有预算了可以拆下来做移动硬盘性价比很高。三星PM981A是OEM产品,就是大批量给电脑厂的,性格比高,但是有翻车几率。可以理解为工包。铠侠就是原来的东芝小白怕翻车的话还是上sn750或者RD10机械硬盘机械硬盘垂直式,东芝P300和DT01,西数1T蓝盘,希捷1T(ST1000DM010),博客文章会详细列出机械硬盘信息欢迎查询。垂直和叠瓦的区别建议百度。最后上图:
2020年08月14日
370 阅读
0 评论
0 点赞
2020-07-24
SpingMVC中Utils工具类静态方法调用Service层
引言之前在百度、CSDN上查询了各种方法,一直都是空指针异常,原因就是static问题。先上图。之前把service层用@PostConstruct赋值后就直接用静态去获取成Settings就是这里出的问题。解决对于定义的Static变量赋值问题应该把调用的service层以及获取数据全部放在init初始化里。就不会报错。对于方法而言就直接调用就行。下面是代码@Component public class MailConfig { @Autowired private SettingsService settingsService; public static MailConfig mailConfig; private static final String PROPERTIES_DEFAULT = "mailConfig.properties"; public static String host; public static Integer port; public static String userName; public static String passWord; public static String emailForm; public static String timeout; public static String personal; public static Properties properties; @PostConstruct public void init(){ mailConfig = this; mailConfig.settingsService = this.settingsService; try { MailSettings ms = JSON.parseObject(mailConfig.settingsService.getSettings().getMailSettings(), MailSettings.class); host = ms.getMailHost(); port = new Integer(ms.getMailPort()); userName = ms.getMailUsername(); passWord = ms.getMailPassword(); emailForm = ms.getMailUsername(); timeout = ms.getMailTimeout(); personal = ms.getPersonal(); }catch (Exception e) { e.printStackTrace(); } } public static void xx(){ mailConfig.settingsService.xx(); } }
2020年07月24日
527 阅读
1 评论
0 点赞
1
...
7
8
9
...
15