加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

采用list传输格式的webservice实现控制远程设备

发布时间:2020-12-16 23:14:33 所属栏目:安全 来源:网络整理
导读:? 前些天在弄一个远程指令控制传感设备的程序,大体思路是这样的:用webservice作为中间服务程序,各平台作为客户端。客户端点击开启按钮调用webservice,webservice向传感设备发送开启指令,webservice和设备之间为TCP连接,分别为socketcliet和socketserve

? 前些天在弄一个远程指令控制传感设备的程序,大体思路是这样的:用webservice作为中间服务程序,各平台作为客户端。客户端点击开启按钮调用webservice,webservice向传感设备发送开启指令,webservice和设备之间为TCP连接,分别为socketcliet和socketserver。二者会保持10秒的连接时间,传感设备数据会保存在webservice数据库中,10秒之后把数据封装成list传给平台客户端。如下图所示:


相关技术:

? ??webService:axis2框架,该框架相关部署不在赘述了

? ? 数据库:mysql数据库

? ? 采用线程池和NIO保证数据非阻塞

?

?

? ? ? ? ??当平台发送一条指令时会开启一个线程,该线程作为socket客户端与传感设备的路由(socketserver端)进行通信。线程都通过线程池进行管理,当与设备通信超时后(这里为10秒)会关闭该线程 重新放回池中。

? ? ? ? ? 为防止socketclient端阻塞,socket采用NIO流进行传输,以防止阻塞的发生。

? ? ? ? ? webservice向平台返回数据采用list方式,将查询结果封装成model对象 再将model放到list,采用这种方式更利于表结构数据传输而且提高传输效率。下面是平台调用webservice的代码:

public class test {
	public static void main(String[] args) throws Exception{
		List<HashMap<String,Object>> returns = new ArrayList<HashMap<String,Object>>();
		RPCServiceClient serviceClient = new RPCServiceClient();
		Options options = serviceClient.getOptions();
		EndpointReference targetEPR = new EndpointReference("http://192.168.1.100:8080/XML/services/HelloWorld");
		options.setTo(targetEPR);
		QName opAddEntry = new QName("http://jdbc.mysql.com","getList2");
		Object[] so = serviceClient.invokeBlocking(opAddEntry,new Object[] {"美女"},new Class[] {Object[].class });
		if (so.length > 0) {
			if (so[0] instanceof Object[]) {
				Object[] elements = (Object[]) so[0];
				for (Object o : elements) {
					HashMap<String,Object> maps = new HashMap<String,Object>();
					OMElementImpl ome = (OMElementImpl) o;
					maps.put(ome.getLocalName(),ome.getText());
					while (ome.getNextOMSibling() != null) {
						ome = (OMElementImpl) ome.getNextOMSibling();
						maps.put(ome.getLocalName(),ome.getText());
					}
					returns.add(maps);
				}
			} else {
				Object ob = so[0];
				if (ob instanceof OMElementImpl == false) {
					HashMap<String,Object>();
					maps.put("simple",ob);
					returns.add(maps);

				} else {
					OMElementImpl ome = (OMElementImpl) so[0];
					HashMap<String,Object>();
					maps.put(ome.getLocalName(),ome.getText());
					returns.add(maps);
				}

			}
			println(returns);
		} else {
			println(returns);;
		}
	}
	
	public static void println(List<HashMap<String,Object>> list) {
		for (HashMap<String,Object> maps : list) {
			System.out.println("------------------");
			Set<String> set = maps.keySet();
			Iterator<String> it = set.iterator();
			while (it.hasNext()) {
				String key = it.next();
				Object value = maps.get(key);
				System.out.print(key + ":" + value + "t");
			}
			System.out.println();
		}
	}

}

客户端所用jar包:http://download.csdn.net/detail/kakarottoz/8136915

webservice服务端方法如下:

public List<Model> getList2(String mac) throws Exception{
    	List<Model> list = new ArrayList<Model>();
    	if(connect(1,mac)){
    		String sql="相应的sql";
        	Connection con = getConn();
        	Statement sta = con.createStatement();
        	ResultSet rs = sta.executeQuery(sql);
        	while(rs.next()){
        		Model m = new Model();
        		m.setTfShuL(rs.getInt("tfShuL"));
        		m.setTfMingC(rs.getString("tfMingC"));
        		m.setTfGuiG(rs.getString("tfGuiG"));
        		m.setTfPinM(rs.getString("tfPinM"));
        		m.setTfDaL(rs.getString("tfDaL"));
        		m.setTfZhuDW(rs.getString("tfZhuDW"));
        		list.add(m);
        	}
    	}
    	return list;
	}

? 开启线程的connect方法如下:

public boolean connect(int machid,String mac) throws Exception{
		try{
			oz oz = new oz();
			oz.initClient("192.168.1.110",8899,machid,mac);
			Thread td = new Thread(oz);
			pool.submit(td);             //线程池
			Thread.sleep(8000);              
			
		}catch(Exception e){
			System.out.println(e.getLocalizedMessage());
			return false;
		}
		return true;
		
	}

?oz是一个自己实现的线程对象,里面也实现了一个NIO的socket客户端,可与传感设备组成的网络进行通信。代码如下:

 public class oz implements Runnable {
	private final static byte[] hex = "0123456789ABCDEF".getBytes();  
	private Selector selector;
	Statement sta;
	ByteBuffer buffer = ByteBuffer.allocate(21);
	private byte[] command=null;
	private static String mac;
	
	public void initClient(String ip,int port,int machid,String mac) throws Exception {
		command=new byte[11];
		command[0]=(byte)0xA0;
		command[1]=0x00;
		command[2]=0x04;
		command[3]=0x00;
		command[4]=0x00;
		command[5]=0x00;
		command[6]=0x00;
		command[7]=0x01;
		command[8]=(byte)0xA0;
		command[9]=0x04;
		command[10]=(byte)0xB7;
		Connection con = getConn();
		sta = con.createStatement();
		// 获得一个Socket通道orz
		this.mac=mac;
		SocketChannel channel = SocketChannel.open();
		// 设置通道为非阻塞
		channel.configureBlocking(false);
		// 获得一个通道管理器
		this.selector = Selector.open();

		// 客户端连接服务器,其实方法执行并没有实现连接,需要在listen()方法中调
		// 用channel.finishConnect();才能完成连接
		channel.connect(new InetSocketAddress(ip,port));
		// 将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_CONNECT事件。
		channel.register(selector,SelectionKey.OP_CONNECT);
	}

	/**
	 * 处理读取服务端发来的信息 的事件
	 * @param key
	 * @throws IOException
	 */
	public void read(SelectionKey key) throws IOException {
		// 和服务端的read方法一样
		 SocketChannel channel = (SocketChannel) key.channel();  
	        // 创建读取的缓冲区  
	        ByteBuffer buffer = ByteBuffer.allocate(14);  
	        channel.read(buffer);  
	        byte[] data = buffer.array();  
//	      String msg = new String(data).trim();  
	        String msg = Bytes2HexString(data);
	        System.out.println("服务端收到信息:"+msg);  
	        try {
				insert(msg,sta);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally{
				channel.close();
			}
//	        ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes());  
	}

	
	/**
	 * author:
	 * time:2014-10-14
	 * @param rfid rfid号
	 * @param sta 数据集合对象
	 * @return
	 * @throws Exception
	 */
	public int insert(String rfid,Statement sta) throws Exception{
		int n=0;
		//int boo = sta.executeUpdate("delete from statistics");
		System.out.println(rfid);
		String sql="insert into realrfid(rfid,realtime,mac) values('"+rfid.substring(4,28)+"',NOW(),'2','"+mac+"')  ";
		System.out.println(sql);
		n = sta.executeUpdate(sql);
		return n;
	}
	
	
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			try {
				int keys = selector.select(10000);
				if (keys == 0) {
					System.out.println("链接已经结束");
					
					break;
				}
				// 获得selector中选中的项的迭代器
				Iterator ite = this.selector.selectedKeys().iterator();
				while (ite.hasNext()) {
					SelectionKey key = (SelectionKey) ite.next();
					// 删除已选的key,以防重复处理
					ite.remove();
					// 连接事件发生
					if (key.isConnectable()) {
						SocketChannel channel = (SocketChannel) key.channel();
						// 如果正在连接,则完成连接
						if (channel.isConnectionPending()) {
							channel.finishConnect();
							channel.register(this.selector,SelectionKey.OP_READ);
						}
						// 设置成非阻塞
						channel.configureBlocking(false);

						// 在这里可以给服务端发送信息哦
						channel.write(ByteBuffer.wrap(command));
						// 在和服务端连接成功之后,为了可以接收到服务端的信息,需要给通道设置读的权限。

						// 获得了可读的事件
					} else if (key.isReadable()) {
						// SocketChannel channel = (SocketChannel)
						// key.channel();
						// channel.read(buffer);
						// byte[] data = buffer.array();
						// String rfid = Bytes2HexString(data);
						// insert(rfid,sta);
						read(key);
					}

				}
			} catch (Exception e) {
				System.out.println(e.getLocalizedMessage());
			}

		}
	}
	
	public static String Bytes2HexString(byte[] b) {  
	    byte[] buff = new byte[2 * b.length];  
	    for (int i = 0; i < b.length; i++) {  
	        buff[2 * i] = hex[(b[i] >> 4) & 0x0f];  
	        buff[2 * i + 1] = hex[b[i] & 0x0f];  
	    }  
	    return new String(buff);  
	}
	
	
	 private static Connection getConn() throws Exception
     {     
		 Connection conn=null;
           String type= "mysql";
            if(type=="mysql" ){
           Class. forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("");
           }
            else if ("sqlserver" .equals(type)){
           Class. forName("net.sourceforge.jtds.jdbc.Driver");
           }
            return conn;
     }

}


? ? ? ? ?以上就是一个简单地通过webservice实现平台和硬件设备的通信实例,使用webservice可以适应多种平台 便于更新扩展同时便于数据的集中处理,其他好处想必大家日后会慢慢发现。。NIO可防止阻塞提高传输效率。

? ? ? ? 还有很多问题有待解决,比如数据的排队问题、线程和socket的优化等等。欢迎大家多多指正

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读