【Websoket】实时推送图像数据,前端实时显示

来源:互联网 发布:计划提醒软件 编辑:程序博客网 时间:2024/05/22 09:22

1. 如何建立WebSocket   

      1.1  前端代码 Index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>">
<title>My WebSocket</title>
</head>


<body>
Welcome<br/>
NickName:<input type='text' name='nickName' value='admin' id='nickName'>
<br />
<input id="text" type="text" />
<button onclick="send();">Send</button>
<button id='close' onclick="closeWebSocket();">Close</button>

<div id="message" style="height: 250px;width: 280px;border: 1px solid; overflow: auto;"></div>

<img src="" id="image">

</body>




<script type="text/javascript">
      var websocket = null;
      var nickName = document.getElementById('nickName').value;
      
      //判断当前浏览器是否支持WebSocket
      if('WebSocket' in window){
          websocket = new WebSocket("ws://localhost:8080/WebSocketDemo/websocket1");//新建一个WebSocket(chrome firefox等浏览器已经集成了websocket模块)
      }
      else{
          alert('Not support websocket')
      }
     
      //websocket.binaryType="arraybuffer";
      //注册一些信息    
      websocket.onerror = WSonError;
       
      websocket.onopen = WSonOpen;//socket建立后触发
       
      websocket.onmessage = WSonMessage;//socket收到消息后触发  
       
      websocket.onclose = WSonClose;  
      
      window.onbeforeunload = WSonBeforeUnload;
      
      function setMessageInnerHTML(innerHTML){
          document.getElementById('message').innerHTML += innerHTML + '<br/>';
      }
      function WSonOpen(){
     setMessageInnerHTML("成功进入聊天室");
      }
      function WSonError(){
     setMessageInnerHTML("发生错误");
      }
      function WSonMessage(event){
     
     var json=JSON.parse(event.data);
     
     //document.getElementById('message').innerHTML+='<div id="image" style="width:500px; height:300px; border:1px solid"></div>';
     //var img=new Image();
     //img.src="data:image/*;base64,"+json.image;
     //document.body.appendChild(img);
     document.getElementById('image').src="data:image/*;base64,"+json.image;
      }
      function WSonClose(){
     setMessageInnerHTML("退出聊天室");
      }
      
      function closeWebSocket(){
     websocket.close();
      }
      function WSonBeforeUnload(){
     websocket.close();
      }
      function send(){
     var NowNickName = document.getElementById('nickName').value;
          var message = document.getElementById('text').value;
          websocket.send(NowNickName + ' 说:' +message);
      }
      
  </script>
</html>

   1.2服务端

package com.socket;




import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArraySet;


import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;


import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;






@ServerEndpoint(
value="/websocket1",  //这个值和前端的websocket = new WebSocket("ws://localhost:8080/WebSocketDemo/websocket1")是匹////配的
encoders={ImageEncoder.class}//此处在后面再讲  先放着
)
public class MyWebSocket {


private static int onlineCount = 0;


private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();


private Session session;

private boolean isFirstCon=true;
private MyThreads myThread1=null;


@OnOpen
public void onOpen(Session session){
this.session = session;
webSocketSet.add(this);
addOnlineCount();           //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());


}


@OnClose
public void onClose(){
webSocketSet.remove(this);  //从set中删除
webSocketSet.remove("");
subOnlineCount();           //在线数减1   
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}


@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来自客户端的消息:" + message);




//群发消息
for(MyWebSocket item: webSocketSet){             
try {
item.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}


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


public void sendMessage(String message){


String myFileNames[]=getFileNames("C:\\Users\\CSU-Beyond\\Desktop\\1");//发送消息  这里将路径修改为你自己的路径

//注意 文件夹中只能是图片文件 如jpg   png格式等
for(int i=0;i<myFileNames.length;i++){
MyImage myimage=new MyImage(myFileNames[i]);//这事我自己定义的一个类    为了将数据进行封装  因为有时

//我们的数据并不仅仅是图像  甚至包含图像拍摄的地点  时间等很多信息     这个类后面会给出
try{
session.getBasicRemote().sendObject(myimage);//去看websocket中的Basic源码  会发现里面有sendText(String text)

//////sendBinary(ByteBuffer data)   sendObject(Object data) 三个主要方式            我理解 其实主要就两个方法,

//sendBinary  和 sendText,因为sendObject方法的实现过程中要用到编码器,必须将Object编码成string或者 ByteBuffer才//可使用,否则会报错。这会儿就用到了前面提到的

//@ServerEndpoint(
//value="/websocket1",  //这个值和前端的websocket = new //WebSocket("ws://localhost:8080/WebSocketDemo/websocket1")是匹////配的
//encoders={ImageEncoder.class}//在调用sendObject的时候会先调用ImageEncoder这个类,当然这个类也是         自/////定//义类    下一步介绍
//)


Thread.sleep(10);
}
catch(Exception e){

}

}
}


public static synchronized int getOnlineCount() {
return onlineCount;
}


public static synchronized void addOnlineCount() {
MyWebSocket.onlineCount++;
}


public static synchronized void subOnlineCount() {
MyWebSocket.onlineCount--;
}

private String[] getFileNames(String path){
ArrayList<String> filenames=new ArrayList<String>();
File di=new File(path);
if(!di.exists()){
System.out.println("路径不存在");
return null;
}

File files[]=di.listFiles();
for(int i=0;i<files.length;i++){
if(files[i].isFile()){
filenames.add(files[i].getPath());
}
}

return filenames.toArray(new String[filenames.size()]);
}


}

2. 如何对图片进行编码   

      本例采用  将图片编码为Base64的字符串格式,然后将字符串编辑为Json格式(此处要自行下载java.jason.jar包,版本自己决定 一般没什么问题),然后发送出去,由前端接收

        2.1  ImageEncoder.class   

/**
 * 这个类在调用sendObject(Object data)的时候会自动调用
 */
package com.socket;
import javax.websocket.Encoder;



import javax.websocket.EncodeException;
import javax.websocket.EndpointConfig;



import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.json.Json;
import javax.json.JsonObject;
/**
 * @author CSU-Beyond
 *
 */
public class ImageEncoder implements Encoder.Text<MyImage>{

@Override
public void init(EndpointConfig endpointConfig) {
// TODO Auto-generated method stub

}

@Override
public void destroy() {
// TODO Auto-generated method stub

}

@Override
public String encode(MyImage object) throws EncodeException {
// TODO Auto-generated method stub
//这里我传进来的是自定义的类格式  Myimage  后面给出源代码

String imagename=object.getImageFullName();
byte[] imageBytes=object.getBinaryImage();
String base64Image=Base64.encode(imageBytes);

JsonObject jsonobj=Json.createObjectBuilder().add("name", imagename).add("image", base64Image).build();//此处很重要    将图像数据按照Base64编码并转换为Json格式


return jsonobj.toString();
}





}

  2.2   MyImage.class

/**
 * 
 */
package com.socket;


import java.io.*;


/**
 * @author CSU-Beyond
 *
 */
public class MyImage {


String fileName="";
byte[] binarayImage=null;
public MyImage(String filename){
this.fileName=filename;
binarayImage=file2Byte(filename);
}

public String getImageFullName(){
return this.fileName;
}

public byte[] getBinaryImage(){
return this.binarayImage;
}



private byte[] file2Byte(String filename){//这部分代码比较繁琐    有更优化的  今天懒得改了
ByteArrayOutputStream outputStream=null;
BufferedInputStream bufInputStream=null;
File file=new File(filename);
try{
if(!file.exists()){throw new FileNotFoundException("文件不存在");}
outputStream=new ByteArrayOutputStream((int)file.length());
bufInputStream=new BufferedInputStream(new FileInputStream(file));

byte[] tempbuf=new byte[(int) file.length()];
int len=bufInputStream.read(tempbuf,0,tempbuf.length);
outputStream.write(tempbuf,0,len);
return outputStream.toByteArray();
}
catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
return null;
}
finally{
try{
if(null!=bufInputStream){
bufInputStream.close();
}
if(null!=outputStream){
outputStream.close();
}
}
catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}

}

}

}

至此  代码都贴出来了   但其实讲解还少一步

3  前端显示Base64格式图像

var json=JSON.parse(event.data);//代码在index.jsp中
       
      
       document.getElementById('image').src="data:image/*;base64,"+json.image;//代码在index.jsp中

有问题可以邮箱沟通   刚开始学习javaweb 欢迎交流  liangji@csu.ac.cn    另外csdn有我上传的源代码http://download.csdn.net/detail/qq_20038925/9828572

0 0