https://my.oschina.net/yushulx/blog/298140

How to Implement a Java WebSocket Server for Image Transmission with Jetty

创建一个从WebSocketHandler继承的类WSHandler

  1. import org.eclipse.jetty.websocket.api.Session;
  2. import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
  3. import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
  4. import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
  5. import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
  6. import org.eclipse.jetty.websocket.api.annotations.WebSocket;
  7. import org.eclipse.jetty.websocket.server.WebSocketHandler;
  8. import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
  9.  
  10. @WebSocket
  11. public class WSHandler extends WebSocketHandler {
  12.  
  13.     @OnWebSocketClose
  14.     public void onClose(int statusCode, String reason) {
  15.     }
  16.  
  17.     @OnWebSocketError
  18.     public void onError(Throwable t) {
  19.     }
  20.  
  21.     @OnWebSocketConnect
  22.     public void onConnect(Session session) {
  23.     }
  24.  
  25.     @OnWebSocketMessage
  26.     public void onMessage(String message) {
  27.     }
  28.  
  29.     @Override
  30.     public void configure(WebSocketServletFactory factory) {
  31.         // TODO Auto-generated method stub
  32.         factory.register(WSHandler.class);
  33.     }
  34. }

设置一个端口和Handler,启动Server:

  1. public static void main(String[] args) throws Exception {
  2.     Server server = new Server(2014);
  3.     server.setHandler(new WSHandler());
  4.     server.setStopTimeout(0);
  5.     server.start();
  6.     server.join();
  7. }

JavaScript客户端

写一个简单的测试。

Index.htm:

  1. <!DOCTYPE html>
  2. <html>
  3.     <body>
  4.         <script src="websocket.js"></script>
  5.     </body>
  6. </html>

Websocket.js:

  1. var ws = new WebSocket("ws://127.0.0.1:2014/");
  2.  
  3. ws.onopen = function() {
  4.     alert("Opened");
  5.     ws.send("I'm client");
  6. };
  7.  
  8. ws.onmessage = function (evt) { 
  9. };
  10.  
  11. ws.onclose = function() {
  12.     alert("Closed");
  13. };
  14.  
  15. ws.onerror = function(err) {
  16.     alert("Error: " + err);
  17. };

图像传输

功能:

  • 从网页中主动获取图像

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

代码修改

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

在index.htm中添加一个按钮元素和一个图片元素:

  1. <!DOCTYPE html>
  2. <html>
  3.     <body>
  4.         <h1>WebSocket Image Display</h1>
  5.         <input type="button" id="button" value="image" ><br>
  6.         <img id="image"></<img>
  7.         <script src="websocket.js"></script>
  8.     </body>
  9. </html>

在Websocket.js中添加下面的代码:

  1. ws.binaryType = "arraybuffer";
  2. var button = document.getElementById("button");
  3. button.onclick = function() {
  4.     ws.send("image"); // send the fetch request
  5. };
  6. ws.onmessage = function (evt) { // display the image
  7.     var bytes = new Uint8Array(evt.data);
  8.     var data = "";
  9.     var len = bytes.byteLength;
  10.     for (var i = 0; i < len; ++i) {
  11.         data += String.fromCharCode(bytes[i]);
  12.     }
  13.     var img = document.getElementById("image");
  14.     img.src = "data:image/png;base64,"+window.btoa(data);
  15. };

服务端收到消息之后,发送图片:

  1. public void onMessage(String message) {
  2.         System.out.println("Message: " + message);
  3.         if (message.equals("image")) {
  4.             System.out.println("session: " + mSession);
  5.             if (mSession != null) {
  6.                 try {
  7.                     File f = new File("image\\github.jpg");
  8.                     BufferedImage bi = ImageIO.read(f);
  9.                     ByteArrayOutputStream out = new ByteArrayOutputStream();
  10.                     ImageIO.write(bi, "png", out);
  11.                     ByteBuffer byteBuffer = ByteBuffer.wrap(out.toByteArray());
  12.                     mSession.getRemote().sendBytes(byteBuffer);
  13.                     out.close();
  14.                     byteBuffer.clear();
  15.  
  16.                 } catch (IOException e) {
  17.                     e.printStackTrace();
  18.                 }
  19.             }
  20.         }
  21.     }

从服务端发送数据到客户端。

在服务端的UI上添加两个按钮,一个用来加载本地图片,一个用来发送图片:

  1. package com.ui;
  2.  
  3. import java.awt.BorderLayout;
  4. import java.awt.Toolkit;
  5. import java.awt.event.ActionEvent;
  6. import java.awt.event.ActionListener;
  7. import java.awt.image.BufferedImage;
  8. import java.io.ByteArrayOutputStream;
  9. import java.io.File;
  10. import java.io.IOException;
  11. import java.util.ArrayList;
  12.  
  13. import javax.imageio.ImageIO;
  14. import javax.swing.ImageIcon;
  15. import javax.swing.JButton;
  16. import javax.swing.JFileChooser;
  17. import javax.swing.JFrame;
  18. import javax.swing.JLabel;
  19. import javax.swing.JPanel;
  20. import javax.swing.SwingUtilities;
  21. import javax.swing.UIManager;
  22. import javax.swing.filechooser.FileNameExtensionFilter;
  23.  
  24. import com.server.WSHandler;
  25. import com.server.WebSocketServer;
  26.  
  27. public class UIMain extends JPanel
  28.                              implements ActionListener {
  29.     private JButton mLoad, mSend;
  30.     private JFileChooser mFileChooser;
  31.     private JLabel mImage;
  32.     private byte[] mData;
  33.     private WebSocketServer mWebSocketServer;
  34.  
  35.     public UIMain() {
  36.         super(new BorderLayout());
  37.  
  38.         //Create a file chooser
  39.         mFileChooser = new JFileChooser();
  40.         FileNameExtensionFilter filter = new FileNameExtensionFilter(
  41.                 ".png.jpg", "png","jpg");
  42.         mFileChooser.setFileFilter(filter);
  43.         mLoad = new JButton("Load");
  44.         mLoad.addActionListener(this);
  45.  
  46.         mSend = new JButton("Send");
  47.         mSend.addActionListener(this);
  48.         mSend.setEnabled(false);
  49.  
  50.         // button panel
  51.         JPanel buttonPanel = new JPanel(); 
  52.         buttonPanel.add(mLoad);
  53.         buttonPanel.add(mSend);
  54.         add(buttonPanel, BorderLayout.PAGE_START);
  55.  
  56.         // image panel
  57.         JPanel imageViewer = new JPanel();
  58.         mImage = new JLabel();
  59.         mImage.setSize(480, 640);
  60.         imageViewer.add(mImage);
  61.         add(imageViewer, BorderLayout.CENTER);
  62.  
  63.         // WebSocketServer
  64.         mWebSocketServer = new WebSocketServer();
  65.         mWebSocketServer.start();
  66.     }
  67.  
  68.     @Override
  69.     public void actionPerformed(ActionEvent e) {
  70.  
  71.     }
  72.  
  73.     private static void createAndShowGUI() {
  74.         //Create and set up the window.
  75.         JFrame frame = new JFrame("WebSocket Demo");
  76.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  77.  
  78.         //Add content to the window.
  79.         frame.add(new UIMain());
  80.  
  81.         //Display the window.
  82.         frame.pack();
  83.         frame.setVisible(true);
  84.         frame.setResizable(false);
  85.         frame.setSize(480, 700);
  86.  
  87.         double width = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
  88.         double height = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
  89.         int frameWidth = frame.getWidth();
  90.         int frameHeight = frame.getHeight();
  91.         frame.setLocation((int)(width - frameWidth) / 2, (int)(height - frameHeight) / 2);
  92.     }
  93.  
  94.     public static void main(String[] args) {
  95.  
  96.         SwingUtilities.invokeLater(new Runnable() {
  97.             @Override
  98.             public void run() {
  99.                 UIManager.put("swing.boldMetal", Boolean.FALSE); 
  100.                 createAndShowGUI();
  101.             }
  102.         });
  103.     }
  104. }

为了防止UI阻塞,Websocket server需要在线程中创建:

  1. package com.server;
  2.  
  3. import org.eclipse.jetty.server.Server;
  4.  
  5. public class WebSocketServer extends Thread{
  6.  
  7.     @Override
  8.     public void run() {
  9.         // TODO Auto-generated method stub
  10.         super.run();
  11.  
  12.         try {
  13.             Server server = new Server(2014);
  14.             server.setHandler(new WSHandler());
  15.             server.setStopTimeout(0);
  16.             server.start();
  17.             server.join();
  18.         } catch (Exception e) {
  19.             // TODO Auto-generated catch block
  20.             e.printStackTrace();
  21.         }
  22.     }
  23. }

在按钮事件中添加图片添加和发送功能:

  1. public void sendImage(byte[] data) {
  2.         if (mSession == null)
  3.             return;
  4.  
  5.         try {           
  6.             ByteBuffer byteBuffer = ByteBuffer.wrap(data);
  7.             mSession.getRemote().sendBytes(byteBuffer);
  8.             byteBuffer.clear();
  9.         } catch (IOException e) {
  10.             e.printStackTrace();
  11.         }
  12.     }
  13.  
  14. @Override
  15.     public void actionPerformed(ActionEvent e) {
  16.  
  17.         if (e.getSource() == mLoad) {
  18.  
  19.             int returnVal = mFileChooser.showOpenDialog(UIMain.this);
  20.  
  21.             if (returnVal == JFileChooser.APPROVE_OPTION) {
  22.                 File file = mFileChooser.getSelectedFile();     
  23.  
  24.                 // load image data to byte array
  25.                 try {           
  26.                     BufferedImage bi = ImageIO.read(file);
  27.                     ByteArrayOutputStream out = new ByteArrayOutputStream();
  28.                     ImageIO.write(bi, "png", out);
  29.                     mData = out.toByteArray();
  30.                     out.close();
  31.                 } catch (IOException exception) {
  32.                     exception.printStackTrace();
  33.                 }
  34.  
  35.                 mImage.setIcon(new ImageIcon(mData));
  36.                 mSend.setEnabled(true);
  37.             }
  38.         } 
  39.         else if (e.getSource() == mSend) {
  40.             ArrayList<WSHandler> sessions = WSHandler.getAllSessions();
  41.             for (WSHandler session : sessions) {
  42.                 session.sendImage(mData);
  43.             }
  44.             mSend.setEnabled(false);
  45.         }
  46.     }

使用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. 配置php时。提示的错误session_start(): Failed to initialize storage module解决办法

    当浏览器输入访问地址后 报这样的错时----session_start(): Failed to initialize storage module 进入到此目录vi /usr/local/php/e ...

  2. js1中call和apply的用法

    js1中call和apply的用法 е辊顷 饼蹭瑭 岚辗疥 碜坪命 笛攮鼠 鲳篝等 ざ遛膜 镀鞭冢蒯 晕 册薷濑 就不是抓了而是人拳啪啪两声两个人都被拳头打在了腿骨 许郾犍 国 ...

  3. cisco 2950 3550 3750 系列交换机密码破解

    破解密码原则:只删除密码 ,不破坏配置#本文中的#号表示注释的意思#第一步. 连接交换机的console口到终端#第二步. 按住交换机面板上的mode键的同时 插入电源,直到sys灯不闪,常亮再松开m ...

  4. 最大边和最小边之差最小的生成树 UVA 1394

    题目大意:给你n个点的图,求苗条度(最大边减最小编)尽量小的生成树 思路:sort以后暴力枚举区间即可 //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #inclu ...

  5. 深入理解javascript执行上下文(Execution Context)

    本文转自:http://blogread.cn/it/article/6178 在这篇文章中,将比较深入地阐述下执行上下文 - Javascript中最基础也是最重要的一个概念.相信读完这篇文章后,你 ...

  6. Inno Setup入门(七)——提供安装语言选项

    Inno Setup安装目录下有一个Languages的文件夹,该文件夹提供了可供使用的语言,通过在脚本中加入[languages]段,可以实现该项功能,实现代码如下: [setup] ;全局设置,本 ...

  7. android--屏幕旋转方法总结

    在介绍之前,我们需要先了解默认情况下android屏幕旋转的机制: 默认情况下,当用户手机的重力感应器打开后,旋转屏幕方向,会导致当前activity发生onDestroy-> onCreate ...

  8. swfupload在chrome中点击上传图片按钮无反应的解决办法

    chrome 22.0.XXXXX dev版上传图片按钮点击无反应原因:是GOOGLE的内建Flash PPAPI外挂所导致的. 问题原因: 由于Google浏览器(Chrome),在最新测试版22. ...

  9. JAVA-面向对象--封装

    1. 如果一个类中没有定义构造函数,会自动加上一个空参的默认构造函数 如果定义了一个构造函数,默认的空参构造函数就没有了. 2. this 当成员变量与局部变量重名的时候,可以使用this来区分.th ...

  10. Arch: Configurations

    the original purpose is to show the steps needed to setup i3 in vbox.. easy. alright, it is a bit mi ...