使用Jetty搭建Java Websocket Server,实现图像传输

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

转载于:https://www.cnblogs.com/donaldlee2008/p/5904871.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值