vue+webrtc(腾讯云) 实现直播功能 pc端+移动端

2024-06-12 07:20

本文主要是介绍vue+webrtc(腾讯云) 实现直播功能 pc端+移动端,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Websocket实现私聊和群聊

  • 1. websocket的概念
    • 1.1. 全双工概念
  • 2. websocket实现聊天室
    • 2.1. WebSocket API
      • 2.1.1. 构造方法
        • 2.1.1.1. 语法
        • 2.1.1.2. 参数
        • 2.1.1.3. 抛出异常
      • 2.1.2. 常量
      • 2.1.3. 属性
      • 2.1.4. 方法
      • 2.1.5. 事件
  • 3. websocket实现群聊或私聊或图片发送
    • 3.1. 项目的最终目录结构
    • 3.2. 依赖注入
    • 3.3. yml文件配置
    • 3.4. 注入ServerEndpointExporter
    • 3.5. Controller代码
    • 3.5. websocket实现群聊
      • 3.5.1. 服务器端代码
      • 3.5.2. 客户端代码
      • 3.5.3. 测试结果
    • 3.6. websocket实现私聊+群聊
      • 3.6.1. 服务器端代码
      • 3.6.2. 客户端代码
      • 3.6.3. SocketConfig代码
      • 3.6.4. 测试结果
    • 3.7. websocket实现聊天图片发送
      • 3.7.1. 服务端代码
      • 3.7.2. 客户端代码
      • 3.7.3. SocketConfig代码
      • 3.7.4. 测试结果

1. websocket的概念

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

1.1. 全双工概念

全双工是通讯传输的一个术语。通信允许数据在两个方面上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时进行信号的双向传输(A—>B的同时B—>A)。单工指:只允许A向B传送信息,而B不能向A传送。

2. websocket实现聊天室

2.1. WebSocket API

WebSocket对象提供了用户创建和管理WebSocket连接,以及通过该连接发送和接收数据的API。

2.1.1. 构造方法
2.1.1.1. 语法

WebSocket(url [, protocols]);

2.1.1.2. 参数
  1. url:要连接的url,WebSocket服务器的url
  2. protocols:可选参数,一个协议字符串或者一个包含协议字符串的数组。这些字符串用于指定子协议,这样单个服务器可以实现多个WebSocket子协议。如果不指定协议字符串,则假定为空字符串。
2.1.1.3. 抛出异常

SECURITY_ERR:正在尝试连接的端口被阻止。

2.1.2. 常量
  1. WebSocket.CONNECTING == 0 连接中
  2. WebSocket.OPEN == 1 已连接
  3. WebSocket.CLOSING == 2 正在关闭
  4. WebSocket.CLOSED == 3 已关闭
2.1.3. 属性
  1. WebSocket.binaryType

    使用二进制的数据类型连接

  2. WebSocket.bufferedAmount(只读)

    未发送至服务器的字节数

  3. WebSocket.extensions(只读)

    服务器选择的扩展

  4. WebSocket.onopen

    用户指定连接成功后的回调函数

  5. WebSocket.onmessage

    用户指定从服务器接收到信息时的回调函数

  6. WebSocket.onerror

    用于指定连接失败后的回调函数

  7. WebSocket.onclose

    用于指定连接关闭后的回调函数

  8. WebSocket.url

    websocket的绝对路径

  9. WebSocket.readyState(只读)

    当前的连接状态

  10. WebSocket.protocol(只读)

    服务器选择的下属协议

2.1.4. 方法
  1. WebSocket.close([code, reason])

    关闭当前连接

  2. WebSocket.send(data)

    对要传输的数据进行排队

2.1.5. 事件

使用addEventListener()监听或将一个事件监听器赋值给本接口的oneventname属性,来监听下面的事件:

  1. open

    当一个WebSocket连接成功时触发,也可以通过onopen属性来设置

  2. message

    当一个WebSocket收发数据时触发,也可以通过onmessage属性来设置

  3. error

    当一个WebSocket连接因错误而关闭时触发,也可以通过onerror属性来设置

  4. close

    当一个WebSocket连接被关闭时触发,也可以通过onclose属性来设置

3. websocket实现群聊或私聊或图片发送

本文使用springboot+freemarker+websocket实现代码

3.1. 项目的最终目录结构

本图片分为三个小的项目:1.websocket实现群聊;2.websocket实现群聊和私聊;3.websocket实现聊天内容可以为图片

3.2. 依赖注入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.AttackingApe.demo</groupId><artifactId>webSocket</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>net.sourceforge.nekohtml</groupId><artifactId>nekohtml</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.72</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins><resources><resource><directory>src/main/resources</directory></resource></resources></build>
</project>

3.3. yml文件配置

server:port: 20713tomcat:uri-encoding: UTF-8
spring:freemarker:suffix: .ftlcharset: UTF-8content-type: text/htmlhttp:encoding:charset: UTF-8force: trueenabled: true

3.4. 注入ServerEndpointExporter

package com.AttackingApe.demo.webSocket.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** @author PengPan* @version 1.0* @date 2020/7/14 18:50*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

3.5. Controller代码

package com.AttackingApe.demo.webSocket.Controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;import java.io.IOException;
import java.util.Map;/*** websocket应用* @author PengPan* @version 1.0* @date 2020/7/13 14:34*/
@RestController
@Slf4j
public class WebsocketController {@RequestMapping("/websocketTest")public ModelAndView sendMessage(Map<String, Object> map) throws IOException{try{log.info("跳转到websocket页面上");return new ModelAndView("webSocketClients", map);}catch (Exception e){log.info("页面跳转发生错误:{}", e.getMessage());map.put("msg", "请求错误");return new ModelAndView("error", map);}}
}

3.5. websocket实现群聊

实现内容:连接websocket的用户都可以进行聊天并显示所有人聊天以及对应的昵称。

3.5.1. 服务器端代码
package com.AttackingApe.demo.webSocket.util;import com.AttackingApe.demo.webSocket.Pojo.SocketConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;/*** @author PengPan* @version 1.0* @date 2020/7/15 18:23*/
@ServerEndpoint(value = "/websocket/{nickname}")
@Component
@Slf4j
public class MyWebsocket {private static Map<String, Session> map = new HashMap<>();private static CopyOnWriteArraySet<MyWebsocket> clients = new CopyOnWriteArraySet<>();private Session session;private String nickname;@OnOpenpublic void onOpen(Session session, @PathParam("nickname") String nickname){this.session = session;this.nickname = nickname;clients.add(this);log.info("有新用户加入,当前人数为:", clients.size());this.session.getAsyncRemote().sendText(nickname + "已加入连接,当前人数为:" + clients.size());}@OnClosepublic void onClose(){clients.remove(this);log.info("有用户断开连接,当前人数为:{}", clients.size());}@OnMessagepublic void onMessage(String message, Session session, @PathParam("nickname") String nickname){log.info("来自客户端:{}发来的消息:{}", nickname, message);broadcast(nickname + ":" + message);}@OnErrorpublic void onError(Session session, Throwable error){log.error("出现错误");error.printStackTrace();}/*** 自定义群发消息* @param message*/public void broadcast(String message){for (MyWebsocket websocket : clients){//异步发送消息websocket.session.getAsyncRemote().sendText(message);}}
}
3.5.2. 客户端代码
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>My WebSocket</title><style>#message{margin-top:40px;border:1px solid gray;padding:20px;}</style>
</head>
<body>
昵称:<input type="text" id="nickname"/>
<button οnclick="conectWebSocket()">连接WebSocket</button>
<button οnclick="closeWebSocket()">断开连接</button>
<hr />
<br />
消  息:<input id="text" type="text" /><button οnclick="send()">发送消息</button>
<div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;function conectWebSocket(){var nickname = document.getElementById("nickname").value;if(nickname == "" || nickname == null){alert("请输入昵称");return;}//判断当前浏览器是否支持WebSocketif ('WebSocket'in window) {websocket = new WebSocket("ws://10.4.4.83:20713/websocket/" + nickname);} else {alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function() {setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function(event) {setMessageInnerHTML("Loc MSG: 成功建立连接");}//接收到消息的回调方法websocket.onmessage = function(event) {setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose = function() {setMessageInnerHTML("Loc MSG:关闭连接");}//监听窗口关闭事件,当窗口关闭时,主动去关闭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>
3.5.3. 测试结果

在这里插入图片描述在这里插入图片描述

3.6. websocket实现私聊+群聊

实现内容:A可以在公屏上输入内容,大家都可以看见。也可以选择输入频道,只和每一个人聊天。

3.6.1. 服务器端代码
package com.AttackingApe.demo.webSocket.util;import com.AttackingApe.demo.webSocket.Pojo.SocketConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;/*** @author PengPan* @version 1.0* @date 2020/7/15 18:23*/
@ServerEndpoint(value = "/websocket/{nickname}")
@Component
@Slf4j
public class MyWebsocket {private static Map<String, Session> map = new HashMap<>();private static CopyOnWriteArraySet<MyWebsocket> clients = new CopyOnWriteArraySet<>();private Session session;private String nickname;@OnOpenpublic void onOpen(Session session, @PathParam("nickname") String nickname){this.session = session;this.nickname = nickname;map.put(session.getId(), session);clients.add(this);log.info("有新用户加入,当前人数为:", clients.size());this.session.getAsyncRemote().sendText(nickname + "已成功连接(其频道号为:" + session.getId() + "),当前在线人数为:" + clients.size());}@OnClosepublic void onClose(){clients.remove(this);log.info("有用户断开连接,当前人数为:{}", clients.size());}@OnMessagepublic void onMessage(String message, Session session, @PathParam("nickname") String nickname){log.info("来自客户端:{}发来的消息:{}", nickname, message);SocketConfig socketConfig;ObjectMapper objectMapper = new ObjectMapper();try{socketConfig = objectMapper.readValue(message, SocketConfig.class);if(socketConfig.getType() == 1){  //私聊socketConfig.setFromUser(session.getId());Session fromSession = map.get(socketConfig.getFromUser());Session toSession = map.get(socketConfig.getToUser());if(toSession != null){  //接受者存在,发送以下消息给接受者和发送者fromSession.getAsyncRemote().sendText(nickname + ":" + socketConfig.getMsg());toSession.getAsyncRemote().sendText(nickname + ":" + socketConfig.getMsg());}else{  //发送者不存在,发送以下消息给发送者fromSession.getAsyncRemote().sendText("频道号不存在或对方不在线");}}else{  //群聊broadcast(nickname + ":" + socketConfig.getMsg());}}catch (Exception e){log.error("发送消息出错");e.printStackTrace();}}@OnErrorpublic void onError(Session session, Throwable error){log.error("出现错误");error.printStackTrace();}/*** 自定义群发消息* @param message*/public void broadcast(String message){for (MyWebsocket websocket : clients){//异步发送消息websocket.session.getAsyncRemote().sendText(message);}}
}
3.6.2. 客户端代码
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>My WebSocket</title><style>#message{margin-top:40px;border:1px solid gray;padding:20px;}</style>
</head>
<body>
昵称:<input type="text" id="nickname"/>
<button οnclick="conectWebSocket()">连接WebSocket</button>
<button οnclick="closeWebSocket()">断开连接</button>
<hr />
<br />
消  息:<input id="text" type="text" />
频道号:<input id="toUser" type="text"/>
<button οnclick="send()">发送消息</button>
<div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;function conectWebSocket(){var nickname = document.getElementById("nickname").value;if(nickname == "" || nickname == null){alert("请输入昵称");return;}//判断当前浏览器是否支持WebSocketif ('WebSocket'in window) {websocket = new WebSocket("ws://10.4.4.83:20713/websocket/" + nickname);} else {alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function() {setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function(event) {setMessageInnerHTML("Loc MSG: 成功建立连接");}//接收到消息的回调方法websocket.onmessage = function(event) {setMessageInnerHTML(event.data);}//连接关闭的回调方法websocket.onclose = function() {setMessageInnerHTML("Loc MSG:关闭连接");}//监听窗口关闭事件,当窗口关闭时,主动去关闭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 toUser = document.getElementById('toUser').value;var socketConfig = {msg:message,toUser:toUser};if(toUser == "" || toUser == null){socketConfig.type = 0;}else{socketConfig.type = 1;}websocket.send(JSON.stringify(socketConfig));}
</script>
</html>
3.6.3. SocketConfig代码
package com.AttackingApe.demo.webSocket.Pojo;import lombok.Data;/*** @author PengPan* @version 1.0* @date 2020/7/16 15:41*/
@Data
public class SocketConfig {//聊天类型 0:群聊  1:私聊private int type;//发送者private String fromUser;//接受者private String toUser;//消息private String msg;//消息类型 1:文本  2:图片private int code;
}
3.6.4. 测试结果

在这里插入图片描述在这里插入图片描述在这里插入图片描述

3.7. websocket实现聊天图片发送

实现内容:聊天的时候可以传入图片。

3.7.1. 服务端代码
package com.AttackingApe.demo.webSocket.util;import com.AttackingApe.demo.webSocket.Pojo.SocketConfig;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;/*** @author PengPan* @version 1.0* @date 2020/7/15 18:23*/
@ServerEndpoint(value = "/websocket/{nickname}")
@Component
@Slf4j
public class MyWebsocket {private static Map<String, Session> map = new HashMap<>();private static CopyOnWriteArraySet<MyWebsocket> clients = new CopyOnWriteArraySet<>();private Session session;private String nickname;@OnOpenpublic void onOpen(Session session, @PathParam("nickname") String nickname){this.session = session;this.nickname = nickname;map.put(session.getId(), session);clients.add(this);log.info("有新用户加入,当前人数为:", clients.size());JSONObject jsonObject = new JSONObject();jsonObject.put("msg",nickname + "已成功连接(其频道号为:" + session.getId() + "),当前在线人数为:" + clients.size());jsonObject.put("code", 1);this.session.getAsyncRemote().sendText(jsonObject.toJSONString());}@OnClosepublic void onClose(){clients.remove(this);log.info("有用户断开连接,当前人数为:{}", clients.size());}@OnMessagepublic void onMessage(String message, Session session, @PathParam("nickname") String nickname){log.info("来自客户端:{}发来的消息:{}", nickname, message);SocketConfig socketConfig;ObjectMapper objectMapper = new ObjectMapper();JSONObject jsonObject = new JSONObject();jsonObject.put("code", JSONObject.parseObject(message).get("code"));try{socketConfig = objectMapper.readValue(message, SocketConfig.class);jsonObject.put("nickname", nickname + ":");if(socketConfig.getType() == 1){  //私聊socketConfig.setFromUser(session.getId());Session fromSession = map.get(socketConfig.getFromUser());Session toSession = map.get(socketConfig.getToUser());if(toSession != null){  //接受者存在,发送以下消息给接受者和发送者jsonObject.put("msg", socketConfig.getMsg());fromSession.getAsyncRemote().sendText(jsonObject.toJSONString());toSession.getAsyncRemote().sendText(jsonObject.toJSONString());}else{  //发送者不存在,发送以下消息给发送者jsonObject.put("msg", "频道号不存在或对方不在线");fromSession.getAsyncRemote().sendText("频道号不存在或对方不在线");}}else{  //群聊jsonObject.put("msg", socketConfig.getMsg());broadcast(jsonObject.toJSONString());}}catch (Exception e){log.error("发送消息出错");e.printStackTrace();}}@OnErrorpublic void onError(Session session, Throwable error){log.error("出现错误");error.printStackTrace();}/*** 自定义群发消息* @param message*/public void broadcast(String message){for (MyWebsocket websocket : clients){//异步发送消息websocket.session.getAsyncRemote().sendText(message);}}
}
3.7.2. 客户端代码
<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>My WebSocket</title><style>#message{margin-top:40px;border:1px solid gray;padding:20px;}</style>
</head>
<body>
昵称:<input type="text" id="nickname"/>
<button οnclick="conectWebSocket()">连接WebSocket</button>
<button οnclick="closeWebSocket()">断开连接</button>
<hr />
<br />
消  息:<input id="text" type="text" />
频道号:<input id="toUser" type="text"/>
<button οnclick="send()">发送消息</button>
<input type="file" id="file" οnchange="chooseFile()"/>
<div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;function conectWebSocket(){var nickname = document.getElementById("nickname").value;if(nickname == "" || nickname == null){alert("请输入昵称");return;}//判断当前浏览器是否支持WebSocketif ('WebSocket'in window) {websocket = new WebSocket("ws://10.4.4.83:20713/websocket/" + nickname);} else {alert('Not support websocket')}//连接发生错误的回调方法websocket.onerror = function() {setMessageInnerHTML("error");};//连接成功建立的回调方法websocket.onopen = function(event) {setMessageInnerHTML("Loc MSG: 成功建立连接");}//接收到消息的回调方法websocket.onmessage = function(event) {var json = JSON.parse(event.data);if(json.code == 1){setMessageInnerHTML(json.nickname + json.msg);}else if(json.code == 2){setMessageInnerHTML(json.nickname);setIconInnerHTML(json.msg);}}//连接关闭的回调方法websocket.onclose = function() {setMessageInnerHTML("Loc MSG:关闭连接");}//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function() {websocket.close();}}//将文本消息显示在网页上function setMessageInnerHTML(innerHTML) {document.getElementById('message').innerHTML += innerHTML + '<br/>';}//将图片消息显示在网页上function setIconInnerHTML(innerHTML) {document.getElementById('message').innerHTML = document.getElementById('message').innerHTML + '<img width="150px" src='+innerHTML+'>' + '<br/>';}//关闭连接function closeWebSocket() {websocket.close();}//发送文本消息function send() {var message = document.getElementById('text').value;var toUser = document.getElementById('toUser').value;var socketConfig = {code:1,msg:message,toUser:toUser};if(toUser == "" || toUser == null){socketConfig.type = 0;}else{socketConfig.type = 1;}websocket.send(JSON.stringify(socketConfig));}//发送图片消息function chooseFile() {var fileList = document.getElementById("file").files;var type = fileList[0].type;var toUser = document.getElementById('toUser').value;if(fileList.length > 0){var fileReader = new FileReader();fileReader.readAsDataURL(fileList[0]);fileReader.onload = function (e) {var socketConfig = {msg: e.target.result,toUser: toUser,code: 2};if (toUser == "" || toUser == null) {socketConfig.type = 0;} else {socketConfig.type = 1;}websocket.send(JSON.stringify(socketConfig));}}}
</script>
</html>
3.7.3. SocketConfig代码
package com.AttackingApe.demo.webSocket.Pojo;import lombok.Data;/*** @author PengPan* @version 1.0* @date 2020/7/16 15:41*/
@Data
public class SocketConfig {//聊天类型 0:群聊  1:私聊private int type;//发送者private String fromUser;//接受者private String toUser;//消息private String msg;//消息类型 1:文本  2:图片private int code;
}
3.7.4. 测试结果

在这里插入图片描述在这里插入图片描述在这里插入图片描述

# websocket# javascript

这篇关于vue+webrtc(腾讯云) 实现直播功能 pc端+移动端的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1053549

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

vue, 左右布局宽,可拖动改变

1:建立一个draggableMixin.js  混入的方式使用 2:代码如下draggableMixin.js  export default {data() {return {leftWidth: 330,isDragging: false,startX: 0,startWidth: 0,};},methods: {startDragging(e) {this.isDragging = tr

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

js+css二级导航

效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con