flashからXMLSocketでProcessingにデータ送信。

FlashからProcessingへのデータ送信はOSCを使えば簡単に出来る。が、floscを中継したりといまいち美しくない気がする。

のでflashからProcessingへ直接XMLSocketで通信する方法を考えてみた。まあ、結論としてはさらに美しくない気もしますが、気にしない気にしない。


ActionScript側は最低限こんな感じで。
SocketP5.as

package {
	import flash.events.Event;
	import flash.net.XMLSocket;
	
	public class SocketP5{
		
		private var ip:String;
		private var port:uint;

		private var socket:XMLSocket;
		
		/**
			default osc connection is <br />
			IP addres :"127.0.0.1" (localhost)<br />
			java Port number : 5204
		*/

		public function SocketP5(ip:String = "127.0.0.1", port:uint = 5204){
			this.ip = ip;
			this.port = port;
			
			socket = new XMLSocket();
			socket.addEventListener(Event.CONNECT, onConnect);
			socket.connect(ip, port);
		}
		
		private function onConnect(e:Event):void {
			trace("connected !");
		}
		
		public function close():void {
			socket.close();
		}
			
		public function sendStr(data:String):void {
			socket.send(data);
		}
		
	}
}


Processing側、というか普通のJavaですが、
FlashServerとXMLSocketの2つのクラスです。

XMLSocket.java

import java.net.Socket;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import java.lang.Exception;
import java.lang.reflect.Field;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;

import processing.xml.*; 


public class XMLSocket extends Thread {
	// for invoketion 
	private Object obj;
	private Method meth;
	
	// for XMLSocket
	Socket socket;
	BufferedReader in;
	PrintWriter out;
    XMLElement xml;
        
  
	
	public XMLSocket(Object obj, Socket so) {
		this.obj = obj;
		try {
			Class cls = obj.getClass();
			Class[] params = {String.class};
			meth =  cls.getMethod("onFlashEvent", params);
			
			
			
			System.out.println("good!!");
			
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} 
		
		        		
		socket = so;
		try {
			in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
			out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"),true);
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		this.start();
		System.out.println("xmlsocket conectted.......");
	}
	
	public void run() {
		try {
			while(true) {
				String str = "";
				int c = in.read();
				// if disconnected
				if(c == -1) {
					break;
				}
				// flash xml socket '\0'
				while (c != '\0') {
					str += (char)c;
					c = in.read();
				}
				//System.out.println(str);
				
				//  invoke
				try {
					meth.invoke(
						obj,
						new Object[] { str }
						);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (java.lang.reflect.InvocationTargetException e){
					e.printStackTrace();	
				}
			}
			in.close();
			out.close();
			socket.close();
			System.out.println("xmlsocket disconnected");
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	
}

と、まあ、メインのところでonFlashEvent関数にinvokeしています。
変数はStringのみ。

FlashServer.java

import java.net.ServerSocket;
import java.net.Socket;

public class FlashServer extends Thread {
	protected ServerSocket server;
	protected Object obj;
	
	/**
	Make a Server for flash xml socket connection.<br />
	Simply, wait for xmlsocket connection from flash. and Run XMLSocket thread.
	@param port the port number of the server.
	*/
	public FlashServer(Object obj, int port) {
		this.obj = obj;
		try {
			server = new ServerSocket(port);
			System.out.println("waiting connection.......");
		}
		catch (Exception e) {
		  e.printStackTrace();
		}
		this.start();
	}
	
	public void run() {
		try {
			while(true) {
				Socket socket = server.accept();
				new XMLSocket(obj,socket);
			}
		}
		catch(Exception e) {
			e.printStackTrace();
		}			
	}
	
	/** need to call this function before to close the server.
	*/
	public void close() {
		try {
			server.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

こんな感じかな?とりあえずは動いた。