我在TCP模式下使用了OscP5,但我似乎不知道
如何监听tcpclient连接或断开连接等更改。
我将oscp5实例化如下:
tcp = new OscP5(this, TCP_PORT, OscP5.TCP);
但是与tcpserver侦听器相关的任何内容都会导致空引用错误,例如
println(tcp.tcpServer().getListeners());
在此期间,我想到的一个棘手的解决办法是不断地计算连接数:
tcp.tcpServer().size()
如果号码增加,则表示客户机已连接;如果号码减少,则表示客户机已断开连接。问题是,当一个客户机断开连接时,我想不出一种方法来知道断开连接的是哪个IP/客户机ID,除非我有自己的列表,并检查我自己的客户机列表中缺少哪个客户机。这让人觉得很粗糙,而且可能容易出错:
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import javax.swing.JOptionPane;
import netP5.NetListener;
import netP5.NetMessage;
import netP5.NetStatus;
import netP5.TcpClient;
import oscP5.OscEventListener;
import oscP5.OscMessage;
import oscP5.OscP5;
import oscP5.OscStatus;
import processing.core.PApplet;
public class TCPServer extends PApplet implements NetListener,OscEventListener {
public static final int TCP_PORT = 32002;
private OscP5 tcp;
private int maxClients = 100;
private TcpClient[] clients = new TcpClient[maxClients];
private HashMap<String,Integer> clientsMap = new HashMap<String, Integer>();//lookup table to check against duplicates
private int prevSize = 0;//previous tcp server client list size
public void setup() {
size(1000,100);
tcp = new OscP5(this, TCP_PORT, OscP5.TCP);
tcp.addListener(this);
}
public void draw() {
int currSize = tcp.tcpServer().size();//get updated size of clients list
//if there was a change, a client either connected or disconnected
if(currSize > prevSize) connect(tcp.tcpServer().getClient(prevSize));//prevSize = size-1 at this point
if(currSize < prevSize) disconnect();
prevSize = currSize;//update internal client size list
background(255);
for (int i = 0; i < maxClients; i++) {
fill(clients[i] == null ? 255 : 127);
rect(i*10,0,10,10);
}
}
public void oscEvent(OscMessage m) {
println(m);
}
private void connect(TcpClient client){
String ip = client.netAddress().address();
if(clientsMap.get(ip) == null){//if the ip is not a duplicate
int id = getNextAvailableSlot();
clients[id] = client;//keep track of this client
clientsMap.put(ip, id);//and it's ip in the LUT
println("connected " + ip + " at index " + id);
}
}
private void disconnect(){
List<TcpClient> c = Arrays.asList(tcp.tcpServer().getClients());//not very efficient, just lazy piggyback ride for contains
for(int i = 0; i < maxClients; i++){//go through locally stored clients
if(clients[i] != null){//if we one
if(!c.contains(clients[i])) {//check if it's not already on the updated tcp server client list
String ip = clients[i].netAddress().address();
clientsMap.remove(ip);//clear LUT entry
tcp.tcpServer().remove(clients[i]);//disconnect
clients[i].dispose();//close
clients[i] = null;//request cleanup
println("disconnected " + ip);
return;
}
}
}
}
private int getNextAvailableSlot(){
for (int i = 0; i < maxClients; i++)
if(clients[i] == null) return i;
return -1;
}
public static void main(String[] args) {
PApplet.main(TCPServer.class.getSimpleName());
}
@Override
public void netEvent(NetMessage e) {
System.out.println("netEvent:");
System.out.println(e);
}
@Override
public void netStatus(NetStatus s) {
System.out.println("netStatus:");
System.out.println(s);
}
@Override
public void oscStatus(OscStatus s) {
System.out.println("oscStatus:");
System.out.println(s);
}
}
在这种情况下,监控TCP客户端连接/断开连接事件的干净方法是什么?
最佳答案
目前,在OSCP5中还没有实现这一概念。这里有一个类似的discussion。
似乎您必须根据调试信息中的内存地址自己构建一些东西,例如### new Client @ netP5.TcpClient@164b9b6
。我扫描system.out流中的字符串,然后调用方法。
这完全是陈词滥调,但我现在看不到其他的方式。
import java.io.PrintStream;
import oscP5.*;
import netP5.*;
OscP5 oscP5tcpServer;
OscP5 oscP5tcpClient;
NetAddress myServerAddress;
void setup() {
// overwrite standard System.out
System.setOut(new PrintStream(System.out) {
public void println(String s) {
if(s.indexOf("new Client") != -1){
clientConnected(getMemoryAddress(s));
}
super.println(s);
}
// override some other methods?
});
oscP5tcpServer = new OscP5(this, 11000, OscP5.TCP);
oscP5tcpClient = new OscP5(this, "127.0.0.1", 11000, OscP5.TCP);
}
void clientConnected(int memoryAddress){
println("Client connected, with memory address " + memoryAddress);
}
int getMemoryAddress(String s){
return Integer.parseInt(s.substring(s.lastIndexOf('@')+1), 16);
}
void draw() {
}
void mousePressed() {
oscP5tcpClient.send("/test", new Object[] {new Integer(1)});
}
void keyPressed() {
println(oscP5tcpServer.tcpServer().getClients().length);
}
void oscEvent(OscMessage theMessage) {
System.out.println("### got a message " + theMessage);
if(theMessage.checkAddrPattern("/test")) {
OscMessage m = new OscMessage("/response");
m.add("server response: got it");
oscP5tcpServer.send(m,theMessage.tcpConnection());
}
}
关于java - 如何使用OscP5监听tcp更改?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17505058/