Hello处理开发人员,
我正在使用OSCP5通过WiFi链接两个处理草图,一个来自Android设备,另一个来自我的计算机。
我已经尝试过直接在setup()上的新NetAddress上键入我的计算机的IP地址,它运行正常。但是,我认为最好让用户有机会将计算机的IP地址更改为发送消息的位置(它可能会更改IP或更改网络,然后Android应用程序将无法正常工作)。
我正在使用一个文本字段供用户输入IP地址,然后在名为ipAddress的字符串中使用它,该字符串进入进入myRemoteLocation的NetAddress。
这是我的代码(通过电话):
import oscP5.*;
import netP5.*;
import apwidgets.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
PWidgetContainer widgetContainer;
PEditText textField;
PButton button1;
PImage fondo;
boolean ValidIP = false;
String ipAddress = "192.168.0.107";
void setup() {
size(480,800);
smooth();
fondo = loadImage("fondoAnd.jpg");
widgetContainer = new PWidgetContainer(this);
textField = new PEditText(10,40,380,120);
button1 = new PButton(10,190,200,100,"Conectar");
widgetContainer.addWidget(textField);
widgetContainer.addWidget(button1);
oscP5 = new OscP5(this,12000);
myRemoteLocation = new NetAddress(ipAddress,12000);
}
void draw() {
if (ValidIP == true){
widgetContainer.hide();
myRemoteLocation = new NetAddress(ipAddress,12000);
background(fondo);
}
else if (ValidIP == false){
background(0);
textSize(20);
text("Ingrese un IP válido",10,30);
widgetContainer.show();
}
}
void mousePressed(){
OscMessage myMessage = new OscMessage("/test");
myMessage.add(8);
oscP5.send(myMessage, myRemoteLocation);
println("enviomensaje"); //I print this in the console to know if it sends a message
}
void onClickWidget(PWidget widget){
if(widget == button1){
ipAddress = textField.getText();
myRemoteLocation = new NetAddress(ipAddress,12000);
ValidIP = true;
}
}
答案 0 :(得分:1)
我已将OSCP5用于a project,许多Android设备作为OSC客户端,计算机作为OSC服务器。我建议从broadcast sample开始。请注意,服务器从端口32000上的任何IP侦听“/ server / connect”消息。这样您就不需要将android设备的ip硬编码到服务器中,但是在这个阶段你仍然会硬编码ip服务器进入客户端android设备。
我解决这个限制的方法是将“/ server / connect”消息发送给可以收听的所有人(“255.255.255.255”)。一旦服务器连接了ip,它就会将消息发送回客户端。然后,客户端将从该消息中获取IP地址,因此不需要将所有后续消息发送到“255.255.255.255”。
我在Android设备上使用了android SDK,在计算机上使用了Processing,所以我的语法看起来会有所不同,但你应该能够理解OSC部分。这是一个简化版本:
package com.hirschandmann.updclient.network;
import netP5.NetAddress;
import oscP5.OscArgument;
import oscP5.OscEventListener;
import oscP5.OscMessage;
import oscP5.OscP5;
import oscP5.OscStatus;
import android.util.Log;
public class NetMan implements OscEventListener {
public static final int PORT_IN = 12000;
public static final int PORT_OUT = 32000;
public static NetAddress SERVER;
public static NetAddress EVERYTHING = new NetAddress("255.255.255.255",PORT_OUT);
private static final String TAG = "NetMan";
private OscP5 osc;
public NetMan(){
osc = new OscP5(this, PORT_IN);
}
public void oscEvent(OscMessage m) {
String pattern = m.addrPattern();
if(SERVER == null) {
SERVER = new NetAddress(m.address().replace("/", ""), PORT_OUT);
System.out.println(SERVER);
}
}
public void connect(){
Log.d("NetMan","connect");
new ConnectTask().execute();
}
public void disconnect(){
new DisconnectTask().execute();
}
@Override
public void oscStatus(OscStatus status) {
System.out.println(status);
}
}
和ConnectTask:
package com.hirschandmann.udpclient.network;
import netP5.NetAddress;
import oscP5.OscMessage;
import oscP5.OscP5;
import android.os.AsyncTask;
public class ConnectTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
System.out.println("sending connect message: " + NetMan.PORT_OUT);
OscMessage m = new OscMessage("/server/connect",new Object[0]);
try{
OscP5.flush(m,NetMan.SERVER != null ? NetMan.SERVER : NetMan.EVERYTHING);
}catch(NullPointerException e) {
System.err.println(e.getMessage());
}
if(NetMan.SERVER != null) System.out.println("NetMan.SERVER: " + NetMan.SERVER);
return null;
}
}
所以你应该尝试在计算机上使用broacast样本,例如:
import netP5.*;
import apwidgets.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
PWidgetContainer widgetContainer;
PEditText textField;
PButton button1;
PImage fondo;
boolean ValidIP = false;
String ipAddress = "255.255.255.255";
void setup() {
size(480,800);
smooth();
fondo = loadImage("fondoAnd.jpg");
widgetContainer = new PWidgetContainer(this);
textField = new PEditText(10,40,380,120);
button1 = new PButton(10,190,200,100,"Conectar");
widgetContainer.addWidget(textField);
widgetContainer.addWidget(button1);
oscP5 = new OscP5(this,12000);
myRemoteLocation = new NetAddress(ipAddress,12000);
}
void draw() {
if (ValidIP == true){
widgetContainer.hide();
myRemoteLocation = new NetAddress(ipAddress,12000);
background(fondo);
}
else if (ValidIP == false){
background(0);
textSize(20);
text("Ingrese un IP válido",10,30);
widgetContainer.show();
}
}
void mousePressed(){
OscMessage myMessage = new OscMessage("/server/connect");
myMessage.add(8);
oscP5.send(myMessage, myRemoteLocation);
println("enviomensaje"); //I print this in the console to know if it sends a message
}
void onClickWidget(PWidget widget){
if(widget == button1){
ipAddress = textField.getText();
myRemoteLocation = new NetAddress(ipAddress,12000);
ValidIP = true;
}
}
void oscEvent(OscMessage m) {
String pattern = m.addrPattern();
if(ipAddress.equals("255.255.255.255")) {
ipAddress = m.address().replace("/", "");
System.out.println("server is at: " + ipAddress);
}
}
以上代码未经过测试,但应该有所帮助。
请注意,我在UDP模式下使用过OSC。还有一种TCP模式。 使用UDP,您可以扩展到多个ips,但不保证您的消息 将获得交叉,每条消息限制为最多64K的数据。 因为UDP数据包没有确认,所以它比TCP快一点。 使用TCP,所有数据包都可以保证到达另一端,但速度很快 而且缺乏广播能力。您还可以发送超过64K的数据。 在我的应用程序中,我必须发送9MP和12MP图像,所以我使用了UDP和TCP:
我遇到的另一个问题是Android上的wifi速度。 Android设备上的Wifi处理方式与计算机上的处理方式不同。操作系统尽可能地保留电池,但这也意味着如果您的设备上的活动很少,Wifi将进入低延迟模式:它可以节省电池但连接速度非常慢,所以如果您需要通过OSC快速响应这是一个问题。我haven't found a proper solution解决了问题,除了锁定wifi和电源总是打开:交换电池寿命以获得一点Wifi响应。我希望我知道solution to this problem。如果您有任何建议,请分享。
HTH