设为首页 收藏本站
查看: 800|回复: 0

[经验分享] 使用Jetty搭建Java Websocket Server,实现图像传输

[复制链接]

尚未签到

发表于 2017-3-1 12:33:38 | 显示全部楼层 |阅读模式
  https://my.oschina.net/yushulx/blog/298140

How to Implement a Java WebSocket Server for Image Transmission with Jetty
  创建一个从WebSocketHandler继承的类WSHandler



import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.server.WebSocketHandler;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
@WebSocket
public class WSHandler extends WebSocketHandler {
    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
    }
    @OnWebSocketError
    public void onError(Throwable t) {
    }
    @OnWebSocketConnect
    public void onConnect(Session session) {
    }
    @OnWebSocketMessage
    public void onMessage(String message) {
    }
    @Override
    public void configure(WebSocketServletFactory factory) {
        // TODO Auto-generated method stub
        factory.register(WSHandler.class);
    }
}
  设置一个端口和Handler,启动Server:



public static void main(String[] args) throws Exception {
    Server server = new Server(2014);
    server.setHandler(new WSHandler());
    server.setStopTimeout(0);
    server.start();
    server.join();
}
JavaScript客户端
  写一个简单的测试。
  Index.htm:



<!DOCTYPE html>
<html>
    <body>
        <script src="websocket.js"></script>
    </body>
</html>
  Websocket.js:



var ws = new WebSocket("ws://127.0.0.1:2014/");
ws.onopen = function() {
    alert("Opened");
    ws.send("I'm client");
};
ws.onmessage = function (evt) {
};
ws.onclose = function() {
    alert("Closed");
};
ws.onerror = function(err) {
    alert("Error: " + err);
};
图像传输
  功能:


  •   从网页中主动获取图像

DSC0000.png



  •   服务端推送图像到网页中

DSC0001.png


代码修改
  从网页中获取服务端数据。
  在index.htm中添加一个按钮元素和一个图片元素:



<!DOCTYPE html>
<html>
    <body>
        <h1>WebSocket Image Display</h1>
        <input type="button" id="button" value="image" ><br>
        <img id="image"></<img>
        <script src="websocket.js"></script>
    </body>
</html>
  在Websocket.js中添加下面的代码:



ws.binaryType = "arraybuffer";
var button = document.getElementById("button");
button.onclick = function() {
    ws.send("image"); // send the fetch request
};
ws.onmessage = function (evt) { // display the image
    var bytes = new Uint8Array(evt.data);
    var data = "";
    var len = bytes.byteLength;
    for (var i = 0; i < len; ++i) {
        data += String.fromCharCode(bytes);
    }
    var img = document.getElementById("image");
    img.src = "data:image/png;base64,"+window.btoa(data);
};
  服务端收到消息之后,发送图片:



public void onMessage(String message) {
        System.out.println("Message: " + message);
        if (message.equals("image")) {
            System.out.println("session: " + mSession);
            if (mSession != null) {
                try {
                    File f = new File("image\\github.jpg");
                    BufferedImage bi = ImageIO.read(f);
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    ImageIO.write(bi, "png", out);
                    ByteBuffer byteBuffer = ByteBuffer.wrap(out.toByteArray());
                    mSession.getRemote().sendBytes(byteBuffer);
                    out.close();
                    byteBuffer.clear();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  从服务端发送数据到客户端。
  在服务端的UI上添加两个按钮,一个用来加载本地图片,一个用来发送图片:



package com.ui;
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter;
import com.server.WSHandler;
import com.server.WebSocketServer;
public class UIMain extends JPanel
                             implements ActionListener {
    private JButton mLoad, mSend;
    private JFileChooser mFileChooser;
    private JLabel mImage;
    private byte[] mData;
    private WebSocketServer mWebSocketServer;
    public UIMain() {
        super(new BorderLayout());
        //Create a file chooser
        mFileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter(
                ".png.jpg", "png","jpg");
        mFileChooser.setFileFilter(filter);
        mLoad = new JButton("Load");
        mLoad.addActionListener(this);
        mSend = new JButton("Send");
        mSend.addActionListener(this);
        mSend.setEnabled(false);
        // button panel
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(mLoad);
        buttonPanel.add(mSend);
        add(buttonPanel, BorderLayout.PAGE_START);
        // image panel
        JPanel imageViewer = new JPanel();
        mImage = new JLabel();
        mImage.setSize(480, 640);
        imageViewer.add(mImage);
        add(imageViewer, BorderLayout.CENTER);
        // WebSocketServer
        mWebSocketServer = new WebSocketServer();
        mWebSocketServer.start();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
    }
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("WebSocket Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Add content to the window.
        frame.add(new UIMain());
        //Display the window.
        frame.pack();
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setSize(480, 700);
        double width = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        double height = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
        int frameWidth = frame.getWidth();
        int frameHeight = frame.getHeight();
        frame.setLocation((int)(width - frameWidth) / 2, (int)(height - frameHeight) / 2);
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                UIManager.put("swing.boldMetal", Boolean.FALSE);
                createAndShowGUI();
            }
        });
    }
}
  为了防止UI阻塞,Websocket server需要在线程中创建:



package com.server;
import org.eclipse.jetty.server.Server;
public class WebSocketServer extends Thread{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        try {
            Server server = new Server(2014);
            server.setHandler(new WSHandler());
            server.setStopTimeout(0);
            server.start();
            server.join();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
  在按钮事件中添加图片添加和发送功能:



public void sendImage(byte[] data) {
        if (mSession == null)
            return;
        try {           
            ByteBuffer byteBuffer = ByteBuffer.wrap(data);
            mSession.getRemote().sendBytes(byteBuffer);
            byteBuffer.clear();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
@Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == mLoad) {
            int returnVal = mFileChooser.showOpenDialog(UIMain.this);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = mFileChooser.getSelectedFile();     
                // load image data to byte array
                try {           
                    BufferedImage bi = ImageIO.read(file);
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    ImageIO.write(bi, "png", out);
                    mData = out.toByteArray();
                    out.close();
                } catch (IOException exception) {
                    exception.printStackTrace();
                }
                mImage.setIcon(new ImageIcon(mData));
                mSend.setEnabled(true);
            }
        }
        else if (e.getSource() == mSend) {
            ArrayList<WSHandler> sessions = WSHandler.getAllSessions();
            for (WSHandler session : sessions) {
                session.sendImage(mData);
            }
            mSend.setEnabled(false);
        }
    }

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348833-1-1.html 上篇帖子: 如何用Web服务器搭建自己的Jetty服务器 下篇帖子: 嵌入式服务器jetty,让你更快开发web
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表