在做投屏出现的一个坑

  • Post author:
  • Post category:其他



我使用TCP与手机端建立链接时如果有一次失败后面都不会再成功试了很多方法最终找到了问题。。。。

ServiceSocket没有设置超时时间 setSoTimeOut

大致代码如下:

public class ServiceUtils {




private  ServerSocket service ;



private static int port=1000;






private ServiceUtils(){




try {




service = new  ServerSocket(port);



service.setSoTimeout(3000);//上次就是忘了加这句



} catch (IOException e) {




e.printStackTrace();



}



}



static {




Properties prop = new Properties();



InputStream inStream = BusinessAuditAction.class



.getResourceAsStream(“/config/pathconfig.properties”);



try {




prop.load(inStream);



String sport = prop.getProperty(“webScreenPort”,”1000″);



port=Integer.parseInt(sport);



} catch (Exception e) {




throw new RuntimeException(e);



} finally {




if (inStream != null) {




try {




inStream.close();



} catch (IOException e) {




inStream = null;



e.printStackTrace();



}



}



}



}






static class Inner{




private static ServiceUtils instance = new ServiceUtils();



}






public static ServiceUtils getInstance(){




return Inner.instance;



}









//获取客户端的Socket



public Socket getClientSocket() throws Exception{




System.out.println(“wait connet”);






Socket socket =  service.accept();



System.out.println(“ip地址:”+socket.getInetAddress().getHostAddress());



return socket;



}






//向客户端发送数据



public void sendData2Client(Socket socket,String jsonStr) throws Exception{




OutputStream os = socket.getOutputStream();



os.write(jsonStr.getBytes());



os.flush();



}




//获取客户端传来的图片



public String readDataFromClient(Socket socket,String unique,String realPath,String outPath){




//获取输入流



InputStream in = null;



try{




in = socket.getInputStream();



byte[] bufs = new byte[1024];



boolean flag = false;



String path = realPath+unique+”\\”;



String picName = null;



int count = 0;






while(true){




//每次读出1024



in.read(bufs,0,1024);



String tempDate = new String(bufs,0,1024);



System.out.println(“getData:”+tempDate);






if(tempDate.startsWith(“file”)){




File dir = new File(path);



if(!dir.exists())





dir.mkdirs();



picName = UUID.randomUUID().toString()+”.jpg”;



String realPath2 = path+picName;



FileOutputStream fos = new FileOutputStream(realPath2);



setData2File(in,fos,tempDate);



flag = true;



}



if(flag)



return outPath+unique+”/”+picName;






Thread.sleep(10);



count++;



if(count>=600)





return outPath+”error.png”;



}






}catch(Exception e){




throw new RuntimeException(e);



}



}












private void setData2File(InputStream in,OutputStream out,String tempLen){




try{




BufferedInputStream bis = new BufferedInputStream(in);



BufferedOutputStream bos = new BufferedOutputStream(out);



tempLen = tempLen.replace(“file”, “”);



long data = Long.parseLong(tempLen.trim());



byte[] buff = new byte[20480];



System.out.println(“file len:”+data);



int len = -1;



long total = 0;



while((len=bis.read(buff))!=-1){




total+=len;



System.out.println(“count:”+total);



bos.write(buff, 0, len);



if(total>=data)





break;



}



bos.flush();



}catch(Exception e){




throw new RuntimeException(e);



}finally{




if(out!=null){




try {




out.close();



System.out.println(“close end”);



} catch (IOException e) {




e.printStackTrace();



}



}






}



}









/**



* 从服务器上删除掉文件



* @param unique



*/



public void deleteFileFromService(String unique,String realPath){




File dir = new File(realPath+unique+”\\”);



delete(dir);



}






//递归删除截图



public static void delete(File dir){




if(dir==null)



return;



if(dir.isDirectory()){




for(File file:dir.listFiles())



delete(file);



}



dir.delete();



}






public static Integer getPort(){




return port;



}

}

DxAction中的代码

public class ForScreenDxAction extends com.hmj.customer.util.CustGeneralAction {




private static final long serialVersionUID = 1L;



private String unique;



private String type;



private Float x1;



private Float y1;



private Float x2;



private Float y2;



private String text;



private Long robotId;



private static ConcurrentHashMap<String, Socket> map = new ConcurrentHashMap<String, Socket>();



private static ServiceUtils instance = ServiceUtils.getInstance();



private static String ip;



private static volatile boolean clearMapFlag = false;// 是否已经添加自动清理map的任务



private static volatile boolean clearPicFlag = false;// 是否添加自动清理图片的任务



public Long getRobotId() {




return robotId;



}



public void setRobotId(Long robotId) {




this.robotId = robotId;



}



public String startForScreen() {




// 开启任务进行map扫描并移除多余东西



if (!clearMapFlag) {




synchronized (ForScreenDxAction.class) {




if (!clearMapFlag) {




TaskThread tasker = TaskThread.getInstance();



tasker.addTask(new Runnable() {



@Override



public void run() {




checkTime();



}



});



clearMapFlag = true;



}



}



}



Socket socket = null;



HttpServletRequest request = ServletActionContext.getRequest();



if (ip == null) {




InetAddress address;



try {




address = InetAddress.getLocalHost();



ip = address.getHostAddress();



} catch (UnknownHostException e) {




e.printStackTrace();



}



}



String realPath = request.getRealPath(“/image/”);



final String temp_Path = realPath;






if(!clearPicFlag){//开启文件任务



synchronized (ForScreenDxAction.class) {




if(!clearPicFlag){




TaskThread tasker = TaskThread.getInstance();



tasker.addTask(new Runnable(){



@Override



public void run() {




File file = new File(temp_Path);



if(file!=null){




File[] dirs = file.listFiles();



if(dirs!=null&&dirs.length>0){




for(File dir:dirs){




if(dir.isFile())



continue;



ServiceUtils.delete(dir);



}



}



}



}



});



clearPicFlag = true;



}



}



}






realPath += “\\”;



String outPath = request.getRequestURL().toString();



String tempPath = request.getServletPath();



outPath = outPath.replace(tempPath, “/image/”).replace(“localhost”, ip);






System.out.println(“………..for screen begain……….”);



if (null != unique) {




socket = map.get(unique);



} else {




String path = outPath + “error.png”;



try{




Writer writer =


ServletActionContext.getResponse().getWriter();



writer.write(path);



writer.flush();



writer.close();



}catch(Exception e){




throw new RuntimeException(e);



}



return null;



}



if (socket == null) {







Map<String, Object> data = new HashMap<String, Object>();



try {




data.put(“type”, 1);



data.put(“ip”, ip);



data.put(“port”, ServiceUtils.getPort());



Robot robot = daoFac.getRobotDao().get(robotId);



String code = robot.getRobotCode();



System.out.println(“robotCode:”+code);





RobotBindRecord record = bizFac.getRobotBindRecordBiz()



.getRecord(robotId);



String wxAccount = record.getWxAccount();



String token = robot.getAccessToken();



AppContext.getContext().setSession(“token”, token);



AppContext.getContext().setSession(“wxAccount”, wxAccount);



AppContext.getContext().setSession(“robotCode”, code);



if (code == null)



return null;



// 发送推送告诉机器人来连接还有微信号的账号和密码



JSONObject ret = XGMsgHelper.getInstance()



.PushSingleDeviceMessage(code, data);



if (ret.getInt(“ret_code”) != 0) {




String path = outPath + “error.png”;



out(path);



return null;



}



System.out



.println(“…………..begain get socket…………”);



socket = instance.getClientSocket();



} catch (Exception e) {




e.printStackTrace();



}



}



// 到这里表示已经获取到了连接



try {




if (map.get(unique) != null) {




String jsonStr = “{\”type\”:\”” + type + “\”,\”x1\”:\”” + x1



+ “\”,\”y1\”:\”” + y1 + “\”,\”x2\”:\”” + x2



+ “\”,\”y2\”:\”” + y2 + “\”,\”text\”:\”” + text + “\”}”;



instance.sendData2Client(socket, jsonStr);



}



} catch (Exception e) {




throw new RuntimeException(e);



}






if(socket==null||!socket.isConnected()){




String path = outPath + “error.png”;



try{




Writer writer =


ServletActionContext.getResponse().getWriter();



writer.write(path);



writer.flush();



writer.close();



}catch(Exception e){




throw new RuntimeException(e);



}



return null;



}



map.put(unique, socket);



String path = instance.readDataFromClient(socket, unique, realPath,



outPath);



System.out.println(“path:” + path);






try {




Writer writer =


ServletActionContext.getResponse().getWriter();



writer.write(path);



writer.flush();



writer.close();



System.out.println(“ok”);



} catch (IOException e) {




System.out.println(“error”);



e.printStackTrace();



}



return null;



}



public String clear() {




Socket socket = null;



if (map != null) {




socket = map.remove(unique);



}



if (socket == null)



return null;



HttpServletRequest request = ServletActionContext.getRequest();



String realPath = request.getRealPath(“/image/”);



realPath += “\\”;



// 删除服务器上缓存的图片



instance.deleteFileFromService(unique, realPath);



HttpServletResponse response = ServletActionContext.getResponse();



response.setCharacterEncoding(“utf-8”);



try {




OutputStream os = socket.getOutputStream();



os.write(“{\”type\”:\”exit\”}”.getBytes());



os.close();



// 拼接要推送的路径



String path = request.getRequestURL().toString();



String tempPath = request.getServletPath();



path = path.replace(tempPath, “/cust/phoneCallBack!changeState.do”);



path = path.replace(“localhost”, ip);



// 发送推送消息



String wxAccount = AppContext.getContext().getSession(“wxAccount”);



AppContext.getContext().removeSession(“wxAccount”);



String token = AppContext.getContext().getSession(“token”);



AppContext.getContext().removeSession(“token”);



Map<String, Object> data = new HashMap<String, Object>();



data.put(“type”, 3);



Map<String, Object> message = new HashMap<String, Object>();



message.put(“type”, 6);



message.put(“wxId”, wxAccount);



message.put(“token”, token);



message.put(“path”, path);



data.put(“message”, message);



// 这个code是重session中拿的



String code = AppContext.getContext().getSession(“robotCode”);



if (code != null)



AppContext.getContext().removeSession(“robotCode”);



XGMsgHelper.getInstance().PushSingleDeviceMessage(code, data);



out(“success”);



} catch (Exception e1) {




e1.printStackTrace();



PrintWriter writer;



try {




writer = response.getWriter();



writer.write(e1.toString());



writer.flush();



writer.close();



} catch (IOException e) {




e.printStackTrace();



}



}



try {




if (socket != null)



socket.close();



} catch (IOException e) {




socket = null;



e.printStackTrace();



}



return null;



}



/**



* 它用于检测map中是否存在未销毁的socket对象根据当前时间和它保存的时间



* 如果大于6分钟表示要销毁



*/



private void checkTime() {




Set<String> keys = map.keySet();



if (keys == null || keys.size() == 0)



return;



List<String> deletes = new LinkedList<String>();



for (String key : keys) {




Long currentTime = new Date().getTime();



Long lastTime = Long.parseLong(key);



if (currentTime – lastTime > 600000)



deletes.add(key);



}



for (String data : deletes) {




Socket socket = map.remove(data);



try {




socket.close();



} catch (IOException e) {




socket = null;



e.printStackTrace();



}



}



}



public String getUnique() {




return unique;



}



public void setUnique(String unique) {




this.unique = unique;



}



public String getType() {




return type;



}



public void setType(String type) {




this.type = type;



}



public Float getX1() {




return x1;



}



public void setX1(Float x1) {




this.x1 = x1;



}



public Float getY1() {




return y1;



}



public void setY1(Float y1) {




this.y1 = y1;



}



public Float getX2() {




return x2;



}



public void setX2(Float x2) {




this.x2 = x2;



}



public Float getY2() {




return y2;



}



public void setY2(Float y2) {




this.y2 = y2;



}



public String getText() {




return text;



}



public void setText(String text) {




this.text = text;



}

}




页面上:

<script type=”text/javascript”>



var flag = true;



function getOffsetLeft(obj) {




var tmp = obj.offsetLeft;



var val = obj.offsetParent;



while (val != null) {




tmp += val.offsetLeft;



val = val.offsetParent;



}



return tmp;



}



function getOffsetTop(obj) {




var tmp = obj.offsetTop;



var val = obj.offsetParent;



while (val != null) {




tmp += val.offsetTop;



val = val.offsetParent;



}



return tmp;



}



unique = new Date().getTime();



var oEn = document.getElementById(‘myimage22’);






var objWidth = 400;



var objHeight = 500;



var x1, y1, x2, y2;



//鼠标按下



oEn.onmousedown = function(ev) {




var oEv = ev || window.event;



var mouseX = oEv.clientX + document.body.scrollLeft;//鼠标x位置



var mouseY = oEv.clientY + document.body.scrollTop;//鼠标y位置



var objTop = getOffsetTop(oEn);//对象x位置



var objLeft = getOffsetLeft(oEn);//对象y位置



//计算点击的相对位置



var objX = mouseX – objLeft;



var objY = mouseY – objTop;



//计算相对比例



x1 = objX / objWidth;



y1 = objY / objHeight;



oEv.preventDefault();



}



//鼠标抬起



oEn.onmouseup = function(ev) {







var oEv = ev || window.event;



var mouseX = oEv.clientX + document.body.scrollLeft;//鼠标x位置



var mouseY = oEv.clientY + document.body.scrollTop;//鼠标y位置



var objTop = getOffsetTop(oEn);//对象x位置



var objLeft = getOffsetLeft(oEn);//对象y位置






//计算点击的相对位置



var objX = mouseX – objLeft;



var objY = mouseY – objTop;






//计算相对比例



x2 = objX / objWidth;



y2 = objY / objHeight;



send(unique, ‘action’, x1, y1, x2, y2);



}



//发送数据



document.getElementById(‘btn1’).onclick = function() {




var value = document.getElementById(‘text’).value;



if (value == null || value == ”) {




alert(“请输入内容!”);



return;



}



send(unique, ‘send’, 0, 0, 0, 0, value);



document.getElementById(‘text’).value = ”;



}



//back键



document.getElementById(‘back’).onclick = function() {




send(unique, ‘back’, 0, 0, 0, 0, null,null);



}



//home键



document.getElementById(‘home’).onclick = function() {




send(unique, ‘home’, 0, 0, 0, 0, null,null);



}






document.getElementById(‘refresh’).onclick = function(){




send(unique,’action’,0,0,0,0,null,null);



}



function send(unique, type, x1, y1, x2, y2, text,robotId) {




var path = “${request.pageContext.contextPath}/cust/forscreen!startForScreen.do”;



if(robotId){




path+=”?robotId=”+robotId;



}






if (flag) {




flag = false;



//调用请求



$.get(path, {




unique : unique,



type : type,



x1 : x1,



y1 : y1,



x2 : x2,



y2 : y2,



text : text



}, function(result) {




oEn.src=””;



oEn.src = result;



flag = true;



});



}



};






function beginForScreen(robotId){




unique = new Date().getTime();



document.getElementById(“myimage22″).src=”images/open.gif”;



document.getElementById(‘f_screen’).style.display = “block”;



send(unique,’home’,0,0,0,0,null,robotId);



}






function closeScreen(id){




$.get(“${request.pageContext.contextPath}/cust/forscreen!clear.do”,{unique : unique},function(result){




if(result==’success’){




document.getElementById(id).style.display = “none”;



}



});



}






function closeShow(id){




document.getElementById(id).style.display = ‘none’;



}









</script>



版权声明:本文为yinbucheng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。