springboot websocket 屏幕共享

这篇具有很好参考价值的文章主要介绍了springboot websocket 屏幕共享。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现springboot websocket同屏浏览功能

1,服务端:websocket screen share\jersey-server,推送给其他客户端。

2,运行websocketTest\client.bat,java websocket client截屏发送到服务端,客户端代码websocketTest\WebSocketClient.java。

3,通过浏览器拉取数据,地址为http://ip:8080/hello 运行顺序,先启动服务端,再启动推送客户端,最后通过浏览器浏览截屏,未实现客户端关闭连接处理,因此关闭客户端时会有异常,可以再重启服务端和推送客户端后重连。

4,可以调节客户端发送截屏频率,以及图片压缩质量。

5,注意,未做优化,本项目运行时占比较网络带宽(可以通过第四步调节发送频率和图片压缩质量调节运行时占用的网络资源)

6,记得修改设置websocket服务器的连接ip

代码下载地址

https://download.csdn.net/download/daqinzl/87976353

实现细节:

1,springboot websocket server enable

WebSocketConfig.java


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter; 


@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }    
}

2, websocket server handler


import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

/**
 * @ServerEndpoint
 * 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@ServerEndpoint(value="/websocket")
@Component
public class WebSocketTest {
    
    private static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
    
    @OnOpen
    public void onOpen(Session session){ 
        System.out.println("加入连接");  
        sessions.put(session.getId(), session);
    }

    @OnClose
    public void onClose(){ 
        System.out.println("关闭连接");
        
    }

    @OnError
    public void onError(Session session, Throwable error){  
       System.out.println("发生错误");
       error.printStackTrace(); 
       //TODO
    }

    /**
     * 收到客户端消息后调用的方法
     * @param messages 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage(maxMessageSize = 5000000)
    public void onMessage(byte[] messages, Session session) {
        try {
          //System.out.println("接收到消息:"+new String(messages,"utf-8"));
            //返回信息
//            String resultStr="{name:\"张三\",age:18,addr:\"上海浦东\"}";
//            //发送字符串信息的 byte数组
//            ByteBuffer bf=ByteBuffer.wrap(resultStr.getBytes("utf-8"));
//            session.getBasicRemote().sendBinary(bf);
            //发送字符串
            //session.getBasicRemote().sendText("测试");


            //接收客户端发来的截屏数据,发送给其他客户端
            Iterator<Session> it = sessions.values().iterator();
            while(it.hasNext()) {
                Session tsession = it.next();
                if(tsession.getId()!=session.getId()) {
                    int len = messages.length;
                    int xx=0;
                    ByteBuffer bf=ByteBuffer.wrap(messages);
                    tsession.getBasicRemote().sendBinary(bf);
                }
            }
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    

3, websocket客户端

3.1 WebSocketClient


import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;


//连接成功  
//tomcat-juli.jar, tomcat-util.jar, tomcat-websocket.jar, websocket-api.jar

public class WebSocketClient {
    
    public static void main(String[] args) {
        try {
            
//            String urlstr = "ws://localhost:8080/websocket";
            String urlstr = "ws://192.168.0.109:8080/websocket";
            
            final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI(urlstr));

            // add listener
            clientEndPoint.addMessageHandler(new WebsocketClientEndpoint.MessageHandler() {
                public void handleMessage(String message) {
                    System.out.println(message);
                }
            });
            
            while(true) 
            {
                try {
                    Thread.sleep(30);
                    byte[] bytes = Util.captureScreen();
                    ByteBuffer bf=ByteBuffer.wrap(bytes);
                    
                    clientEndPoint.sendMessage(bf);                    
                }
                catch(Exception ex) {
                    ex.printStackTrace();
                }
                
            }
            
//            clientEndPoint.close();

        }
//        catch (InterruptedException ex) {
//            System.err.println("InterruptedException exception: " + ex.getMessage());
//        } 
        catch (URISyntaxException ex) {
            ex.printStackTrace();
            System.err.println("URISyntaxException exception: " + ex.getMessage());
        }
    }
   
}

3.2 WebsocketClientEndpoint


import java.net.URI;
import java.nio.ByteBuffer;

import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

/**
 * ChatServer Client
 *
 * @author Jiji_Sasidharan
 */
@ClientEndpoint
public class WebsocketClientEndpoint {

    Session userSession = null;
    private MessageHandler messageHandler;

    public WebsocketClientEndpoint(URI endpointURI) {
        try {
            WebSocketContainer container = ContainerProvider.getWebSocketContainer();
            container.connectToServer(this, endpointURI);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Callback hook for Connection open events.
     *
     * @param userSession the userSession which is opened.
     */
    @OnOpen
    public void onOpen(Session userSession) {
        System.out.println("opening websocket");
        this.userSession = userSession;
    }

    /**
     * Callback hook for Connection close events.
     *
     * @param userSession the userSession which is getting closed.
     * @param reason the reason for connection close
     */
    @OnClose
    public void onClose(Session userSession, CloseReason reason) {
        System.out.println("closing websocket");
        this.userSession = null;
    }

    /**
     * Callback hook for Message Events. This method will be invoked when a client send a message.
     *
     * @param message The text message
     */
    @OnMessage
    public void onMessage(String message) {
        if (this.messageHandler != null) {
            this.messageHandler.handleMessage(message);
        }
        System.out.println("receive :" + message);
    }

    public void close(){
        onClose(userSession, new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "normal close"));
    }
    
    /**
     * register message handler
     *
     * @param msgHandler
     */
    public void addMessageHandler(MessageHandler msgHandler) {
        this.messageHandler = msgHandler;
    }

    /**
     * Send a message.
     *
     * @param message
     */
    public void sendMessage(String message) {
        this.userSession.getAsyncRemote().sendText(message);
    }

    public void sendMessage(ByteBuffer message) {
        this.userSession.getAsyncRemote().sendBinary(message);
    }
    
    /**
     * Message handler.
     *
     * @author Jiji_Sasidharan
     */
    public static interface MessageHandler {

        public void handleMessage(String message);
    }
}

3.3 截屏工具类

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

public class Util {

    private static Robot ro = null;
    private static BufferedImage bi = null;
    private static Dimension di = null;
    private static Rectangle rec = null;

    static {
        try {
            ro = new Robot(); // (通过本地操作)控制鼠标、键盘等实际输入源(java.awt)
            Toolkit tk = Toolkit.getDefaultToolkit(); // AWT组件的抽象父类(java.awt)
            di = tk.getScreenSize();
            rec = new Rectangle(0, 0, di.width, di.height);
        } catch (Exception e) {
//            logger.error("screensyncserver", e);
            e.printStackTrace();
        }        
    }
    
    public static byte[] captureScreen() {

        byte[] bytes = null;
        try {
            bi = ro.createScreenCapture(rec);
            BufferedImage get = bi.getSubimage(0, 0, di.width, di.height);

            // 从截屏中读取
            bytes = imageToBytes(get);
            return bytes;            
            
        } catch (Exception e) {
            //logger.error("getscreenandsend", e);
            e.printStackTrace();
        }
        return null;
    }
    

    private static byte[] imageToBytes(BufferedImage bImage) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            //ImageIO.write(bImage, "jpg", out);
            
            ImageOutputStream ios = ImageIO.createImageOutputStream(out); //var7
            Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg"); 
            ImageWriter writer = iter.next(); 
            ImageWriteParam iwp = writer.getDefaultWriteParam(); 
            iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
//            iwp.setCompressionQuality(1.0f);
            iwp.setCompressionQuality(0.3f);//TODO
            writer.setOutput(ios); 
            writer.write(null, new IIOImage(bImage,null,null),iwp); 
            writer.dispose();
            
        } catch (IOException e) {
            e.printStackTrace();
            //log.error(e.getMessage());
        }
        byte[] ret = out.toByteArray();
        try {
            out.close();
        } catch (IOException e) {
//            logger.error("image2bytes", e);
            e.printStackTrace();
        }
        return ret;
    }
        
}
 

4,浏览器拉取数据


<html>
<head> 
</head>
<body>
    <input id="text" type="text"/>
    <button οnclick="send()">send message</button> 
    <div id="message"></div>
    <!--收到的图片列表-->
    <div id="show"><h3>image:</h3>
    <img id="img" src=""/>
    </div>

</body>

<script type="text/javascript">
    var websocket = null;
    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://192.168.0.109:8080/websocket");
        //websocket默认是传输字符串的,需要改为arraybuffer二进制传输类型
        websocket.binaryType = "arraybuffer";
    }else {
        alert('当前浏览器 Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function () {
        setMessageInnerHTML("WebSocket connect error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function () {
        setMessageInnerHTML("WebSocket connected");
    }

    //接收到消息的回调方法
    websocket.onmessage = function (event) { 
        //将接收到的二进制数据转为字符串
        document.getElementById("img").src="";
        var uInt8Array = new Uint8Array(event.data)
        var i = uInt8Array.length;
        var binaryString = new Array(i);
        while (i--)
        {
          binaryString[i] = String.fromCharCode(uInt8Array[i]);
        }
        var data = binaryString.join('');
     
        var base64 = window.btoa(data);
        //if(src.endsWith("jpeg"))
        var url="data:image/jpeg;base64," + base64;
        //else if(src.endsWith("gif"))
        //var url="data:image/gif;base64," + base64;

        var img = document.getElementById("img");
        img.src=url;
        img.height=1080;
        img.width=1920;        
   
    }

    //连接关闭的回调方法
    websocket.onclose = function () {
        setMessageInnerHTML("WebSocket连接关闭");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        closeWebSocket();
    }
 
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭WebSocket连接
    function closeWebSocket() {
        websocket.close();
    }

    //发送消息
    function send() {
        var message = document.getElementById('text').value; 
        
        //将字符串转换为byte数组
        var bytesArr= stringToByte(message);   
        var bytes =new Uint8Array(bytesArr.length) ;
        for (var i = 0; i < bytes.length; i++) {
            bytes[i]=bytesArr[i];
        }  
        console.log(bytes)
       websocket.send(bytes);
    }
    
    
        //将字符串转为 Array byte数组
        function stringToByte(str) {  
                var bytes = new Array();  
                var len, c;  
                len = str.length;  
                for(var i = 0; i < len; i++) {  
                    c = str.charCodeAt(i);  
                    if(c >= 0x010000 && c <= 0x10FFFF) {  
                        bytes.push(((c >> 18) & 0x07) | 0xF0);  
                        bytes.push(((c >> 12) & 0x3F) | 0x80);  
                        bytes.push(((c >> 6) & 0x3F) | 0x80);  
                        bytes.push((c & 0x3F) | 0x80);  
                    } else if(c >= 0x000800 && c <= 0x00FFFF) {  
                        bytes.push(((c >> 12) & 0x0F) | 0xE0);  
                        bytes.push(((c >> 6) & 0x3F) | 0x80);  
                        bytes.push((c & 0x3F) | 0x80);  
                    } else if(c >= 0x000080 && c <= 0x0007FF) {  
                        bytes.push(((c >> 6) & 0x1F) | 0xC0);  
                        bytes.push((c & 0x3F) | 0x80);  
                    } else {  
                        bytes.push(c & 0xFF);  
                    }  
                }  
                return bytes;  
    
    
            }
            
            //byte数组转字符串
            function byteToString(arr) {
                if(typeof arr === 'string') {
                    return arr;
                }
                var str = '',
                    _arr = arr;
                for(var i = 0; i < _arr.length; i++) {
                    var one = _arr[i].toString(2),
                        v = one.match(/^1+?(?=0)/);
                    if(v && one.length == 8) {
                        var bytesLength = v[0].length;
                        var store = _arr[i].toString(2).slice(7 - bytesLength);
                        for(var st = 1; st < bytesLength; st++) {
                            store += _arr[st + i].toString(2).slice(2);
                        }
                        str += String.fromCharCode(parseInt(store, 2));
                        i += bytesLength - 1;
                    } else {
                        str += String.fromCharCode(_arr[i]);
                    }
                }
            return str;
        }

    
</script>
</html>文章来源地址https://www.toymoban.com/news/detail-515383.html

到了这里,关于springboot websocket 屏幕共享的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 保姆级教程!基于声网 Web SDK实现音视频通话及屏幕共享

    本篇文章主要给小伙伴们分享如何使用声网 SDK 实现 Web 端音视频通话及屏幕共享功能,其中也会涵盖在实践过程中遇到的一些问题,以此记录防止小伙伴们踩坑,同时也希望通过从 0 到 1 实战的分享,能够帮助更多的小伙伴。

    2024年02月16日
    浏览(64)
  • 电脑怎么共享屏幕?电脑屏幕共享软件分享!

    有时我们可能需要远程控制某人的计算机屏幕,例如,为我们的客户提供远程支持,远程帮助朋友或家人解决计算机问题,或在家中与同事完成团队合作。那么,电脑怎么共享屏幕?本文将为大家分享一款免费的电脑屏幕共享软件,助大家轻松共享电脑屏幕。          Any

    2024年02月06日
    浏览(46)
  • springboot+shiro+redis实现session共享和cache共享

    在分布式应用中,若是使用了负载均衡,用户第一次访问,连接的A服务器,进行了登录操作进入了系统,当用户再次操作时,请求被转发到了B服务器,用户并没有在B进行登录,此时用户又来到了登录页面,这是难以理解和接受的,这就引出了session共享。 对于shiro安全框架如

    2024年02月11日
    浏览(35)
  • SpringBoot 实现多个子域共享 cookie

    使用SpringBoot web框架,版本号 2.7.10 现在有两个域名 dev.scd.com.cn,test.scd.com.cn 的服务,登录验证之后,服务器写入 cookie 到响应头,用户只需要登录一次,访问任意一个域都携带cookie 信息 后端服务写入cookie 指定domain为二级域名 .scd.com.cn cookie基础知识 本地模拟多个域的环境,

    2023年04月20日
    浏览(28)
  • 【WebSocket】SpringBoot整合WebSocket实现聊天室(一)

    目录 一、准备 1、引入依赖 2、创建配置类 二、相关注解 首先我们需要在项目中引入依赖,有两种方式。第一种我们可以在创建Spring Boot项目时搜索WebSocket然后勾选依赖 第二种是我们可以直接在项目的pom.xml文件中插入以下依赖 我们需要进行如下配置 ServerEndpointExporter 是一个

    2024年02月13日
    浏览(50)
  • SpringBoot实现WebSocket

    WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议) 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的 Websocket是一个持久化的协议 按照上图这样配置即可,点击下一步 因为本文章只实现websocket功能,所以只勾选

    2024年01月18日
    浏览(32)
  • Springboot对Websocket的实现

    本文章是使用Springboot+WebSocket简单实现一个web界面的聊天室 项目结构如下   首先在springboot项目的pom.xml中导入所需要的依赖包web、websocket以及解析JSON格式的fastjson 2.实现前端登录界面 3.校验账密,并将将用户登录状态存储到session中 4.进入聊天室界面 4.1身份校验后,建立webs

    2024年02月16日
    浏览(32)
  • SpringBoot(java)实现websocket实现实时通信

    WebSockets是一种在Web应用程序中实现实时通信的技术。它允许客户端和服务器之间建立持久的、双向的通信通道,从而使得服务器可以实时向客户端推送数据,而不需要客户端不断地向服务器发起请求。这种实时通信的能力对于需要即时更新数据的应用程序非常有用,比如在线

    2024年04月29日
    浏览(53)
  • SpringBoot集成websocket(4)|(使用okhttp3实现websocket)

    章节 第一章链接: SpringBoot集成websocket(1)|(websocket客户端实现) 第二章链接: SpringBoot集成websocket(2)|(websocket服务端实现以及websocket中转实现) HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。OkHttp是一个高效的HTTP客户

    2024年02月10日
    浏览(42)
  • SpringBoot集成websocket(3)|(websocket调用websocket采用回调方式实现数据互传)

    章节 第一章链接: SpringBoot集成websocket(1)|(websocket客户端实现) 第二章链接: SpringBoot集成websocket(2)|(websocket服务端实现以及websocket中转实现) 本节主要介绍的是springboot实现websocket的客户端服务端,以及客户端与服务端的数据互传。以下为伪代码,业务逻辑删除导致不

    2024年02月12日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包