微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

  前些天在弄一个远程指令控制传感设备的程序,大体思路是这样的:用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的优化等等。欢迎大家多多指正

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐