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);
};

图像传输

功能:

  • 从网页中主动获取图像

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

代码修改

从网页中获取服务端数据。

在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[i]);
    }
    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);
        }
    }

使用Jetty搭建Java Websocket Server,实现图像传输的更多相关文章

  1. Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available

    java.lang.IllegalStateException: Failed to load ApplicationContext    at org.springframework.test.co ...

  2. java websocket学习

    引言: websocket,webservice傻傻分不清楚,都觉得是很高深的东西,理解中的webservice是一种协议,通信协议,类似http协议的那种,比如使用webservice协议调后台接口 ...

  3. GIN+GORILLA=A GOLANG WEBSOCKET SERVER

    鉴于聊天已然成为大部分app的基础功能,而大部分app用户基数有没有辣么大,常用的聊天server架构如xmpp或者消息队列实现之类的用起来还挺麻烦的,有比较难跟网页端做交互,加之H5标准落地,所以w ...

  4. 【IntelliJ IDEA新手入门】IDEA如何快速搭建Java开发环境

    作为IntelliJ IDEA mac新手,IDEA如何快速搭建Java开发环境呢? 今天小编就给大家带来了IntelliJ IDEA mac使用教程,想知道IDEA如何快速搭建Java开发环境?那就 ...

  5. IDEA如何快速搭建Java开发环境

    作为IntelliJ IDEA mac新手,IDEA如何快速搭建Java开发环境呢?今天小编就给大家带来了IntelliJ IDEA mac使用教程,想知道IDEA如何快速搭建Java开发环境? 全局 ...

  6. java WebSocket Demo

    1.IDEA创建Module,结构如图(Tomcat8.0) 2.引入jar包:javax.websocket-api.jar 3.新建WebSocketTest类 import javax.webs ...

  7. 在 Ubuntu 13.10 中搭建Java开发环境 - 懒人版

    本文记录我在Ubuntu 13.10中搭建Java开发环境. 本文环境: Ubuntu 13.10 x64运行在Win7下的VMware Workstation 10中. 1. 安装JDK与JRE s ...

  8. SSD Cloud Hosting - Linode的配置和部署,搭建Java环境

    0.发牢骚 前一个月在淘宝购买了个Jsp空间,挺便宜的,才38元/年.部署了程序,然后ALIMAMA验证网站,一直提示验证失败.最后找卖家,他说可能是因为空间太慢,照他的推荐换了最好的空间,138元/ ...

  9. RedHat7/Windows7搭建JAVA开发环境(Eclipse)

    RedHat7搭建JAVA开发环境 安装JAVA # yum install java 安装Tomcat # yum install tomcat 确认Tomcat版本 # tomcat versio ...

随机推荐

  1. UVa 1395 (最小生成树)

    题目链接:http://vjudge.net/problem/41567/origin 本来想着m^2的复杂度撑不住,对于这种擦着边的复杂度就好慌. 首先对所有的边排个序,然后枚举每个可以构成生成树的 ...

  2. petstore-jdbc

    拖了好多天,终于决定开始写作业了,搞了大半天的把软件安好. jdk(安装与环境配置) Tomcat(安装与环境配置) mysql(安装,同时配置图形化操作界面) eclipse for Javaee ...

  3. 解决ORA-00904: invalid identifier标识符无效

    方法/步骤 1 大部分情况下,此错误是由于引用了不存在的列名导致的.比如select name from Studtent 当studeng表中无name列时,系统就会报此错误. 2 解决思路是,确定 ...

  4. Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html"

    2015-11-16 10:39:17.235 PullDemo[338:60b] Application windows are expected to have a root view contr ...

  5. jquery滚动条加载数据

    //滚动条  $(window).scroll(function () {   var scrollTop = $(this).scrollTop();   var scrollHeight = $( ...

  6. 安卓之PreferenceActivity分享

    PerferenceActivity是什么,看下面的截图: Android的系统截图 乐手设置截图 好了,我们看到Android系统本身就大量用到了PreferenceActivity来对系统进行信息 ...

  7. zk reconnect

    http://blog.csdn.net/hengyunabc/article/details/41450003 http://blog.csdn.net/hengyunabc/article/det ...

  8. SQL Server 2008删除或压缩数据库日志的方法

    SQL Server 2008删除或压缩数据库日志的方法 2010-09-20 20:15 由 于数据库日志增长被设置为“无限制”,所以时间一长日志文件必然会很大,一个400G的数据库居然有600G的 ...

  9. linux ubuntu下如何安装并且切换java版本(Unsupported major.minor version 52.0)

    最近在做一个dcos(数据中心操作系统)的东西,需要用marathon来做进程管理.遗憾的是0.6版本的marathon在API方面很是缺少,换成了0.15版本之后,运行时提示“Unsupported ...

  10. php 版本比较

    判断当前运行的 PHP 版本是否高于或等于你提供的版本号. function is_php($version) { static $_is_php; $version = (string) $vers ...