funktioniert nun soweit mit drei slidern, sogar syncronisiert aus verschiedenen browser fenstern
This commit is contained in:
parent
47f6bd328d
commit
4950b16c39
|
@ -25,75 +25,68 @@ import java.net.UnknownHostException;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import artnet4j.events.ArtNetServerEventAdapter;
|
|
||||||
import artnet4j.events.ArtNetServerListener;
|
|
||||||
import artnet4j.packets.ArtNetPacket;
|
import artnet4j.packets.ArtNetPacket;
|
||||||
import artnet4j.packets.ArtPollReplyPacket;
|
|
||||||
import artnet4j.packets.PacketType;
|
|
||||||
|
|
||||||
public class ArtNet {
|
public class ArtNet {
|
||||||
|
|
||||||
public static final Logger logger =
|
public static final Logger logger = Logger.getLogger(ArtNet.class.getClass().getName());
|
||||||
Logger.getLogger(ArtNet.class.getClass().getName());
|
|
||||||
|
|
||||||
protected static final long ARTPOLL_REPLY_TIMEOUT = 3000;
|
protected static final long ARTPOLL_REPLY_TIMEOUT = 3000;
|
||||||
|
|
||||||
protected static final String VERSION = "0001-20091119";
|
protected static final String VERSION = "0001-20091119";
|
||||||
|
|
||||||
protected ArtNetServer server;
|
protected ArtNetServer server;
|
||||||
protected ArtNetNodeDiscovery discovery;
|
// protected ArtNetNodeDiscovery discovery;
|
||||||
|
|
||||||
public ArtNet() {
|
// public ArtNet() {
|
||||||
logger.info("Art-Net v" + VERSION);
|
// logger.info("Art-Net v" + VERSION);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void addServerListener(ArtNetServerListener l) {
|
// public void addServerListener(ArtNetServerListener l) {
|
||||||
server.addListener(l);
|
// server.addListener(l);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// public void broadcastPacket(ArtNetPacket packet) {
|
||||||
|
// server.broadcastPacket(packet);
|
||||||
|
// }
|
||||||
|
|
||||||
public void broadcastPacket(ArtNetPacket packet) {
|
// public ArtNetNodeDiscovery getNodeDiscovery() {
|
||||||
server.broadcastPacket(packet);
|
// if (discovery == null) {
|
||||||
}
|
// discovery = new ArtNetNodeDiscovery(this);
|
||||||
|
// }
|
||||||
public ArtNetNodeDiscovery getNodeDiscovery() {
|
// return discovery;
|
||||||
if (discovery == null) {
|
// }
|
||||||
discovery = new ArtNetNodeDiscovery(this);
|
|
||||||
}
|
|
||||||
return discovery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
server = new ArtNetServer();
|
server = new ArtNetServer();
|
||||||
server.addListener(new ArtNetServerEventAdapter() {
|
// server.addListener(new ArtNetServerEventAdapter() {
|
||||||
|
// @Override
|
||||||
@Override
|
// public void artNetPacketReceived(ArtNetPacket packet) {
|
||||||
public void artNetPacketReceived(ArtNetPacket packet) {
|
// logger.fine("packet received: " + packet.getType());
|
||||||
logger.fine("packet received: " + packet.getType());
|
// if (discovery != null && packet.getType() == PacketType.ART_POLL_REPLY) {
|
||||||
if (discovery != null
|
// discovery.discoverNode((ArtPollReplyPacket) packet);
|
||||||
&& packet.getType() == PacketType.ART_POLL_REPLY) {
|
// }
|
||||||
discovery.discoverNode((ArtPollReplyPacket) packet);
|
// }
|
||||||
}
|
//
|
||||||
}
|
// @Override
|
||||||
|
// public void artNetServerStarted(ArtNetServer artNetServer) {
|
||||||
@Override
|
// logger.fine("server started callback");
|
||||||
public void artNetServerStarted(ArtNetServer artNetServer) {
|
// }
|
||||||
logger.fine("server started callback");
|
//
|
||||||
}
|
// @Override
|
||||||
|
// public void artNetServerStopped(ArtNetServer artNetServer) {
|
||||||
@Override
|
// logger.info("server stopped");
|
||||||
public void artNetServerStopped(ArtNetServer artNetServer) {
|
// }
|
||||||
logger.info("server stopped");
|
// });
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeServerListener(ArtNetServerListener l) {
|
// public void removeServerListener(ArtNetServerListener l) {
|
||||||
server.removeListener(l);
|
// server.removeListener(l);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void setBroadCastAddress(String ip) {
|
// public void setBroadCastAddress(String ip) {
|
||||||
server.setBroadcastAddress(ip);
|
// server.setBroadcastAddress(ip);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void start() throws SocketException, ArtNetException {
|
public void start() throws SocketException, ArtNetException {
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
|
@ -102,38 +95,38 @@ public class ArtNet {
|
||||||
server.start();
|
server.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startNodeDiscovery() throws ArtNetException {
|
// public void startNodeDiscovery() throws ArtNetException {
|
||||||
getNodeDiscovery().start();
|
// getNodeDiscovery().start();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (discovery != null) {
|
// if (discovery != null) {
|
||||||
discovery.stop();
|
// discovery.stop();
|
||||||
}
|
// }
|
||||||
if (server != null) {
|
if (server != null) {
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Sends the given packet to the specified Art-Net node.
|
// * Sends the given packet to the specified Art-Net node.
|
||||||
*
|
// *
|
||||||
* @param packet
|
// * @param packet
|
||||||
* @param node
|
// * @param node
|
||||||
*/
|
// */
|
||||||
public void unicastPacket(ArtNetPacket packet, ArtNetNode node) {
|
// public void unicastPacket(ArtNetPacket packet, ArtNetNode node) {
|
||||||
server.unicastPacket(packet, node.getIPAddress());
|
// server.unicastPacket(packet, node.getIPAddress());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* Sends the given packet to the specified IP address.
|
// * Sends the given packet to the specified IP address.
|
||||||
*
|
// *
|
||||||
* @param packet
|
// * @param packet
|
||||||
* @param adr
|
// * @param adr
|
||||||
*/
|
// */
|
||||||
public void unicastPacket(ArtNetPacket packet, InetAddress adr) {
|
// public void unicastPacket(ArtNetPacket packet, InetAddress adr) {
|
||||||
server.unicastPacket(packet, adr);
|
// server.unicastPacket(packet, adr);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the given packet to the specified IP address.
|
* Sends the given packet to the specified IP address.
|
||||||
|
|
|
@ -1,132 +1,132 @@
|
||||||
/*
|
///*
|
||||||
* This file is part of artnet4j.
|
// * This file is part of artnet4j.
|
||||||
*
|
// *
|
||||||
* Copyright 2009 Karsten Schmidt (PostSpectacular Ltd.)
|
// * Copyright 2009 Karsten Schmidt (PostSpectacular Ltd.)
|
||||||
*
|
// *
|
||||||
* artnet4j is free software: you can redistribute it and/or modify
|
// * artnet4j is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
// * it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
// * the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
// * (at your option) any later version.
|
||||||
*
|
// *
|
||||||
* artnet4j is distributed in the hope that it will be useful,
|
// * artnet4j is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
// * GNU General Public License for more details.
|
||||||
*
|
// *
|
||||||
* You should have received a copy of the GNU General Public License
|
// * You should have received a copy of the GNU General Public License
|
||||||
* along with artnet4j. If not, see <http://www.gnu.org/licenses/>.
|
// * along with artnet4j. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
// */
|
||||||
|
//
|
||||||
package artnet4j;
|
//package artnet4j;
|
||||||
|
//
|
||||||
import java.net.InetAddress;
|
//import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
//import java.util.ArrayList;
|
||||||
import java.util.List;
|
//import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
//import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Logger;
|
//import java.util.logging.Logger;
|
||||||
|
//
|
||||||
import artnet4j.events.ArtNetDiscoveryListener;
|
//import artnet4j.events.ArtNetDiscoveryListener;
|
||||||
import artnet4j.packets.ArtPollPacket;
|
//import artnet4j.packets.ArtPollPacket;
|
||||||
import artnet4j.packets.ArtPollReplyPacket;
|
//import artnet4j.packets.ArtPollReplyPacket;
|
||||||
|
//
|
||||||
public class ArtNetNodeDiscovery implements Runnable {
|
//public class ArtNetNodeDiscovery implements Runnable {
|
||||||
|
//
|
||||||
public static final int POLL_INTERVAL = 10000;
|
// public static final int POLL_INTERVAL = 10000;
|
||||||
|
//
|
||||||
public static final Logger logger = Logger
|
// public static final Logger logger = Logger
|
||||||
.getLogger(ArtNetNodeDiscovery.class.getClass().getName());
|
// .getLogger(ArtNetNodeDiscovery.class.getClass().getName());
|
||||||
|
//
|
||||||
protected final ArtNet artNet;
|
// protected final ArtNet artNet;
|
||||||
protected ConcurrentHashMap<InetAddress, ArtNetNode> discoveredNodes = new ConcurrentHashMap<InetAddress, ArtNetNode>();
|
// protected ConcurrentHashMap<InetAddress, ArtNetNode> discoveredNodes = new ConcurrentHashMap<InetAddress, ArtNetNode>();
|
||||||
protected List<ArtNetNode> lastDiscovered = new ArrayList<ArtNetNode>();
|
// protected List<ArtNetNode> lastDiscovered = new ArrayList<ArtNetNode>();
|
||||||
protected List<ArtNetDiscoveryListener> listeners = new ArrayList<ArtNetDiscoveryListener>();
|
// protected List<ArtNetDiscoveryListener> listeners = new ArrayList<ArtNetDiscoveryListener>();
|
||||||
|
//
|
||||||
protected boolean isActive = true;
|
// protected boolean isActive = true;
|
||||||
|
//
|
||||||
protected long discoveryInterval;
|
// protected long discoveryInterval;
|
||||||
|
//
|
||||||
private Thread discoveryThread;
|
// private Thread discoveryThread;
|
||||||
|
//
|
||||||
public ArtNetNodeDiscovery(ArtNet artNet) {
|
// public ArtNetNodeDiscovery(ArtNet artNet) {
|
||||||
this.artNet = artNet;
|
// this.artNet = artNet;
|
||||||
setInterval(POLL_INTERVAL);
|
// setInterval(POLL_INTERVAL);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void addListener(ArtNetDiscoveryListener l) {
|
// public void addListener(ArtNetDiscoveryListener l) {
|
||||||
synchronized (listeners) {
|
// synchronized (listeners) {
|
||||||
listeners.add(l);
|
// listeners.add(l);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void discoverNode(ArtPollReplyPacket reply) {
|
// public void discoverNode(ArtPollReplyPacket reply) {
|
||||||
InetAddress nodeIP = reply.getIPAddress();
|
// InetAddress nodeIP = reply.getIPAddress();
|
||||||
ArtNetNode node = discoveredNodes.get(nodeIP);
|
// ArtNetNode node = discoveredNodes.get(nodeIP);
|
||||||
if (node == null) {
|
// if (node == null) {
|
||||||
logger.info("discovered new node: " + nodeIP);
|
// logger.info("discovered new node: " + nodeIP);
|
||||||
node = reply.getNodeStyle().createNode();
|
// node = reply.getNodeStyle().createNode();
|
||||||
node.extractConfig(reply);
|
// node.extractConfig(reply);
|
||||||
discoveredNodes.put(nodeIP, node);
|
// discoveredNodes.put(nodeIP, node);
|
||||||
for (ArtNetDiscoveryListener l : listeners) {
|
// for (ArtNetDiscoveryListener l : listeners) {
|
||||||
l.discoveredNewNode(node);
|
// l.discoveredNewNode(node);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
node.extractConfig(reply);
|
// node.extractConfig(reply);
|
||||||
}
|
// }
|
||||||
lastDiscovered.add(node);
|
// lastDiscovered.add(node);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void removeListener(ArtNetDiscoveryListener l) {
|
// public void removeListener(ArtNetDiscoveryListener l) {
|
||||||
synchronized (listeners) {
|
// synchronized (listeners) {
|
||||||
listeners.remove(l);
|
// listeners.remove(l);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void run() {
|
// public void run() {
|
||||||
try {
|
// try {
|
||||||
while (isActive) {
|
// while (isActive) {
|
||||||
lastDiscovered.clear();
|
// lastDiscovered.clear();
|
||||||
ArtPollPacket poll = new ArtPollPacket();
|
// ArtPollPacket poll = new ArtPollPacket();
|
||||||
artNet.broadcastPacket(poll);
|
// artNet.broadcastPacket(poll);
|
||||||
Thread.sleep(ArtNet.ARTPOLL_REPLY_TIMEOUT);
|
// Thread.sleep(ArtNet.ARTPOLL_REPLY_TIMEOUT);
|
||||||
if (isActive) {
|
// if (isActive) {
|
||||||
synchronized (listeners) {
|
// synchronized (listeners) {
|
||||||
for (ArtNetNode node : discoveredNodes.values()) {
|
// for (ArtNetNode node : discoveredNodes.values()) {
|
||||||
if (!lastDiscovered.contains(node)) {
|
// if (!lastDiscovered.contains(node)) {
|
||||||
discoveredNodes.remove(node.getIPAddress());
|
// discoveredNodes.remove(node.getIPAddress());
|
||||||
for (ArtNetDiscoveryListener l : listeners) {
|
// for (ArtNetDiscoveryListener l : listeners) {
|
||||||
l.discoveredNodeDisconnected(node);
|
// l.discoveredNodeDisconnected(node);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
for (ArtNetDiscoveryListener l : listeners) {
|
// for (ArtNetDiscoveryListener l : listeners) {
|
||||||
l.discoveryCompleted(new ArrayList<ArtNetNode>(
|
// l.discoveryCompleted(new ArrayList<ArtNetNode>(
|
||||||
discoveredNodes.values()));
|
// discoveredNodes.values()));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
Thread.sleep(discoveryInterval
|
// Thread.sleep(discoveryInterval
|
||||||
- ArtNet.ARTPOLL_REPLY_TIMEOUT);
|
// - ArtNet.ARTPOLL_REPLY_TIMEOUT);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (InterruptedException e) {
|
// } catch (InterruptedException e) {
|
||||||
logger.warning("node discovery interrupted");
|
// logger.warning("node discovery interrupted");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void setInterval(int interval) {
|
// public void setInterval(int interval) {
|
||||||
discoveryInterval = Math.max(interval, ArtNet.ARTPOLL_REPLY_TIMEOUT);
|
// discoveryInterval = Math.max(interval, ArtNet.ARTPOLL_REPLY_TIMEOUT);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void start() throws ArtNetException {
|
// public void start() throws ArtNetException {
|
||||||
if (discoveryThread == null) {
|
// if (discoveryThread == null) {
|
||||||
discoveryThread = new Thread(this);
|
// discoveryThread = new Thread(this);
|
||||||
discoveryThread.start();
|
// discoveryThread.start();
|
||||||
} else {
|
// } else {
|
||||||
throw new ArtNetException("discovery already started.");
|
// throw new ArtNetException("discovery already started.");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void stop() {
|
// public void stop() {
|
||||||
isActive = false;
|
// isActive = false;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
|
@ -25,17 +25,11 @@ import java.net.DatagramSocket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import artnet4j.events.ArtNetServerListener;
|
|
||||||
import artnet4j.packets.ArtNetPacket;
|
import artnet4j.packets.ArtNetPacket;
|
||||||
import artnet4j.packets.ArtNetPacketParser;
|
|
||||||
import artnet4j.packets.ArtPollPacket;
|
|
||||||
import artnet4j.packets.PacketType;
|
|
||||||
|
|
||||||
public class ArtNetServer extends ArtNetNode implements Runnable {
|
public class ArtNetServer extends ArtNetNode { // implements Runnable {
|
||||||
|
|
||||||
public static final int DEFAULT_PORT = 0x1936;
|
public static final int DEFAULT_PORT = 0x1936;
|
||||||
|
|
||||||
|
@ -51,7 +45,7 @@ public class ArtNetServer extends ArtNetNode implements Runnable {
|
||||||
protected int receiveBufferSize;
|
protected int receiveBufferSize;
|
||||||
protected boolean isRunning;
|
protected boolean isRunning;
|
||||||
|
|
||||||
protected final List<ArtNetServerListener> listeners;
|
// protected final List<ArtNetServerListener> listeners;
|
||||||
|
|
||||||
public ArtNetServer() {
|
public ArtNetServer() {
|
||||||
this(DEFAULT_PORT, DEFAULT_PORT);
|
this(DEFAULT_PORT, DEFAULT_PORT);
|
||||||
|
@ -61,68 +55,67 @@ public class ArtNetServer extends ArtNetNode implements Runnable {
|
||||||
super(NodeStyle.ST_SERVER);
|
super(NodeStyle.ST_SERVER);
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.sendPort = sendPort;
|
this.sendPort = sendPort;
|
||||||
this.listeners = new ArrayList<ArtNetServerListener>();
|
// this.listeners = new ArrayList<ArtNetServerListener>();
|
||||||
setBufferSize(2048);
|
setBufferSize(2048);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(ArtNetServerListener l) {
|
// public void addListener(ArtNetServerListener l) {
|
||||||
synchronized (listeners) {
|
// synchronized (listeners) {
|
||||||
listeners.add(l);
|
// listeners.add(l);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// public void broadcastPacket(ArtNetPacket ap) {
|
||||||
|
// try {
|
||||||
|
// DatagramPacket packet = new DatagramPacket(ap.getData(), ap
|
||||||
|
// .getLength(), broadCastAddress, sendPort);
|
||||||
|
// socket.send(packet);
|
||||||
|
// for (ArtNetServerListener l : listeners) {
|
||||||
|
// l.artNetPacketBroadcasted(ap);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// logger.warning(e.getMessage());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void removeListener(ArtNetServerListener l) {
|
||||||
|
// synchronized (listeners) {
|
||||||
|
// listeners.remove(l);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public void broadcastPacket(ArtNetPacket ap) {
|
// @Override
|
||||||
try {
|
// public void run() {
|
||||||
DatagramPacket packet = new DatagramPacket(ap.getData(), ap
|
// byte[] receiveBuffer = new byte[receiveBufferSize];
|
||||||
.getLength(), broadCastAddress, sendPort);
|
// DatagramPacket receivedPacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
|
||||||
socket.send(packet);
|
//
|
||||||
for (ArtNetServerListener l : listeners) {
|
// try {
|
||||||
l.artNetPacketBroadcasted(ap);
|
// while (isRunning) {
|
||||||
}
|
// socket.receive(receivedPacket);
|
||||||
} catch (IOException e) {
|
// logger.finer("received new packet");
|
||||||
logger.warning(e.getMessage());
|
// ArtNetPacket packet = ArtNetPacketParser.parse(receivedPacket);
|
||||||
}
|
// if (packet != null) {
|
||||||
}
|
// if (packet.getType() == PacketType.ART_POLL) {
|
||||||
|
// sendArtPollReply(receivedPacket.getAddress(), (ArtPollPacket) packet);
|
||||||
|
// }
|
||||||
|
// for (ArtNetServerListener l : listeners) {
|
||||||
|
// l.artNetPacketReceived(packet);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// socket.close();
|
||||||
|
// logger.info("server thread terminated.");
|
||||||
|
// for (ArtNetServerListener l : listeners) {
|
||||||
|
// l.artNetServerStopped(this);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public void removeListener(ArtNetServerListener l) {
|
// private void sendArtPollReply(InetAddress inetAddress, ArtPollPacket packet) {
|
||||||
synchronized (listeners) {
|
// // TODO send reply with self description
|
||||||
listeners.remove(l);
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
byte[] receiveBuffer = new byte[receiveBufferSize];
|
|
||||||
DatagramPacket receivedPacket = new DatagramPacket(receiveBuffer,
|
|
||||||
receiveBuffer.length);
|
|
||||||
try {
|
|
||||||
while (isRunning) {
|
|
||||||
socket.receive(receivedPacket);
|
|
||||||
logger.finer("received new packet");
|
|
||||||
ArtNetPacket packet = ArtNetPacketParser.parse(receivedPacket);
|
|
||||||
if (packet != null) {
|
|
||||||
if (packet.getType() == PacketType.ART_POLL) {
|
|
||||||
sendArtPollReply(receivedPacket.getAddress(),
|
|
||||||
(ArtPollPacket) packet);
|
|
||||||
}
|
|
||||||
for (ArtNetServerListener l : listeners) {
|
|
||||||
l.artNetPacketReceived(packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
socket.close();
|
|
||||||
logger.info("server thread terminated.");
|
|
||||||
for (ArtNetServerListener l : listeners) {
|
|
||||||
l.artNetServerStopped(this);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendArtPollReply(InetAddress inetAddress, ArtPollPacket packet) {
|
|
||||||
// TODO send reply with self description
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBroadcastAddress(String address) {
|
public void setBroadcastAddress(String address) {
|
||||||
try {
|
try {
|
||||||
|
@ -144,14 +137,15 @@ public class ArtNetServer extends ArtNetNode implements Runnable {
|
||||||
setBroadcastAddress(DEFAULT_BROADCAST_IP);
|
setBroadcastAddress(DEFAULT_BROADCAST_IP);
|
||||||
}
|
}
|
||||||
if (socket == null) {
|
if (socket == null) {
|
||||||
socket = new DatagramSocket(port);
|
// socket = new DatagramSocket(port);
|
||||||
logger.info("Art-Net server started at port: " + port);
|
socket = new DatagramSocket();
|
||||||
for (ArtNetServerListener l : listeners) {
|
// logger.info("Art-Net server started at port: " + port);
|
||||||
l.artNetServerStarted(this);
|
// for (ArtNetServerListener l : listeners) {
|
||||||
}
|
// l.artNetServerStarted(this);
|
||||||
|
// }
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
serverThread = new Thread(this);
|
// serverThread = new Thread(this);
|
||||||
serverThread.start();
|
// serverThread.start();
|
||||||
} else {
|
} else {
|
||||||
throw new ArtNetException(
|
throw new ArtNetException(
|
||||||
"Couldn't create server socket, server already running?");
|
"Couldn't create server socket, server already running?");
|
||||||
|
@ -170,13 +164,14 @@ public class ArtNetServer extends ArtNetNode implements Runnable {
|
||||||
*/
|
*/
|
||||||
public void unicastPacket(ArtNetPacket ap, InetAddress targetAdress) {
|
public void unicastPacket(ArtNetPacket ap, InetAddress targetAdress) {
|
||||||
try {
|
try {
|
||||||
DatagramPacket packet = new DatagramPacket(ap.getData(), ap
|
DatagramPacket packet = new DatagramPacket(ap.getData(), ap.getLength(), targetAdress, sendPort);
|
||||||
.getLength(), targetAdress, sendPort);
|
|
||||||
socket.send(packet);
|
socket.send(packet);
|
||||||
logger.finer("sent packet to: " + targetAdress);
|
logger.finer("sent packet to: " + targetAdress);
|
||||||
for (ArtNetServerListener l : listeners) {
|
|
||||||
l.artNetPacketUnicasted(ap);
|
// for (ArtNetServerListener l : listeners) {
|
||||||
}
|
// l.artNetPacketUnicasted(ap);
|
||||||
|
// }
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warning(e.getMessage());
|
logger.warning(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package de.ctdo.dmx;
|
||||||
|
|
||||||
|
public interface DMXDataChangedListener {
|
||||||
|
|
||||||
|
void DMXDataChanged(int[] dmx512data);
|
||||||
|
|
||||||
|
}
|
|
@ -1,72 +1,52 @@
|
||||||
package de.ctdo.dmx;
|
package de.ctdo.dmx;
|
||||||
|
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
import artnet4j.ArtNet;
|
import artnet4j.ArtNet;
|
||||||
import artnet4j.ArtNetException;
|
import artnet4j.ArtNetException;
|
||||||
import artnet4j.ArtNetNode;
|
import artnet4j.ArtNetNode;
|
||||||
import artnet4j.events.ArtNetDiscoveryListener;
|
|
||||||
import artnet4j.packets.ArtDmxPacket;
|
import artnet4j.packets.ArtDmxPacket;
|
||||||
|
|
||||||
public class Mixer {
|
public class Mixer {
|
||||||
static Mixer instance = new Mixer();
|
static Mixer instance = new Mixer();
|
||||||
final int TICKS_BETWEEN_DMX_SEND = 1000 * 200;
|
final int TICKS_BETWEEN_DMX_SEND = 20;
|
||||||
|
final int DMX_MIN_CHANNEL = 0;
|
||||||
|
final int DMX_MAX_CHANNEL = 512;
|
||||||
|
|
||||||
Logger logger = LoggerFactory.getLogger(Mixer.class);
|
Logger logger = LoggerFactory.getLogger(Mixer.class);
|
||||||
byte[] dmx512databuffer = new byte[512];
|
int[] dmx512databuffer = new int[512];
|
||||||
static int sequenceID = 0;
|
static int sequenceID = 0;
|
||||||
ArtNet artnet = new ArtNet();
|
ArtNet artnet = new ArtNet();
|
||||||
ArtNetNode firstNodeFound = null;
|
ArtNetNode firstNodeFound = null;
|
||||||
long ticksLastBufferFlush = 0;
|
long ticksLastBufferFlush = 0;
|
||||||
|
|
||||||
|
protected final List<DMXDataChangedListener> listeners = new ArrayList<DMXDataChangedListener>();
|
||||||
|
|
||||||
public static Mixer getInstance() {
|
public static Mixer getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addListener(DMXDataChangedListener l) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void removeListener(DMXDataChangedListener l) {
|
||||||
|
synchronized (listeners) {
|
||||||
|
listeners.remove(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Mixer() {
|
private Mixer() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
artnet.start();
|
artnet.start();
|
||||||
|
|
||||||
artnet.getNodeDiscovery().addListener(new ArtNetDiscoveryListener() {
|
|
||||||
@Override
|
|
||||||
public void discoveryCompleted(List<ArtNetNode> nodes) {
|
|
||||||
for (ArtNetNode artNetNode : nodes) {
|
|
||||||
logger.debug(artNetNode.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void discoveredNodeDisconnected(ArtNetNode node) {
|
|
||||||
if( node == firstNodeFound) {
|
|
||||||
firstNodeFound = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void discoveredNewNode(ArtNetNode node) {
|
|
||||||
if(firstNodeFound == null) {
|
|
||||||
firstNodeFound = node;
|
|
||||||
logger.info("found first artnetnode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void discoveryFailed(Throwable t) {
|
|
||||||
logger.error("ArtNetNode discovery failed");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
artnet.startNodeDiscovery();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (ArtNetException e) {
|
catch (ArtNetException e) {
|
||||||
logger.error("ArtNetException... " + e.toString());
|
logger.error("ArtNetException... " + e.toString());
|
||||||
|
@ -79,20 +59,28 @@ public class Mixer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendOutDMXBuffer() {
|
private void sendOutDMXBuffer() {
|
||||||
if(firstNodeFound == null) {
|
// if(firstNodeFound == null) {
|
||||||
logger.info("No ArtNetNode to send data to");
|
// logger.info("No ArtNetNode to send data to");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
ArtDmxPacket dmx = new ArtDmxPacket();
|
ArtDmxPacket dmx = new ArtDmxPacket();
|
||||||
dmx.setUniverse(firstNodeFound.getSubNet(), firstNodeFound.getDmxOuts()[0]);
|
// dmx.setUniverse(firstNodeFound.getSubNet(), firstNodeFound.getDmxOuts()[0]);
|
||||||
|
// dmx.setSequenceID(sequenceID % 255);
|
||||||
|
// dmx.setDMX(dmx512databuffer, dmx512databuffer.length);
|
||||||
|
// artnet.unicastPacket(dmx, firstNodeFound.getIPAddress());
|
||||||
|
dmx.setUniverse(0, 0);
|
||||||
dmx.setSequenceID(sequenceID % 255);
|
dmx.setSequenceID(sequenceID % 255);
|
||||||
dmx.setDMX(dmx512databuffer, dmx512databuffer.length);
|
byte[] arr = new byte[dmx512databuffer.length];
|
||||||
artnet.unicastPacket(dmx, firstNodeFound.getIPAddress());
|
for (int i = 0; i < dmx512databuffer.length; i++) {
|
||||||
|
arr[i] = (byte)dmx512databuffer[i];
|
||||||
|
}
|
||||||
|
dmx.setDMX(arr, arr.length);
|
||||||
|
artnet.unicastPacket(dmx, "192.168.0.90");
|
||||||
|
|
||||||
sequenceID++;
|
sequenceID++;
|
||||||
|
|
||||||
ticksLastBufferFlush = System.currentTimeMillis();
|
ticksLastBufferFlush = System.currentTimeMillis();
|
||||||
logger.debug("Send out DMX Data");
|
// logger.debug("Send out DMX Data");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendOutDMXBufferIfNeeded() {
|
public void sendOutDMXBufferIfNeeded() {
|
||||||
|
@ -102,15 +90,20 @@ public class Mixer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDMX512Channel(int channel, int value) {
|
public void setDMX512Channel(int channel, int value) {
|
||||||
if(channel < 0 || channel > dmx512databuffer.length-1) {
|
if(channel < DMX_MIN_CHANNEL || channel > DMX_MAX_CHANNEL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(value < 0) value = 0;
|
if(value < 0) value = 0;
|
||||||
if(value > 255) value = 255;
|
if(value > 255) value = 255;
|
||||||
|
|
||||||
dmx512databuffer[channel] = (byte)value;
|
dmx512databuffer[channel-1] = value;
|
||||||
|
|
||||||
|
|
||||||
sendOutDMXBufferIfNeeded();
|
sendOutDMXBufferIfNeeded();
|
||||||
|
|
||||||
|
for (DMXDataChangedListener l : this.listeners) {
|
||||||
|
l.DMXDataChanged(dmx512databuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,25 +14,31 @@ import de.ctdo.dmx.Mixer;
|
||||||
public class DMXControllerApplication extends WebSocketApplication {
|
public class DMXControllerApplication extends WebSocketApplication {
|
||||||
Logger logger = LoggerFactory.getLogger(DMXControllerApplication.class);
|
Logger logger = LoggerFactory.getLogger(DMXControllerApplication.class);
|
||||||
|
|
||||||
public WebSocket createSocket(ProtocolHandler handler, WebSocketListener... listeners) {
|
@Override
|
||||||
|
public WebSocket createWebSocket(ProtocolHandler protocolHandler, WebSocketListener... listeners) {
|
||||||
logger.debug("createSocket ");
|
logger.debug("createSocket ");
|
||||||
return new DMXControllerWebSocket(handler, listeners);
|
DMXControllerWebSocket socket = new DMXControllerWebSocket(protocolHandler, listeners);
|
||||||
|
Mixer.getInstance().addListener(socket);
|
||||||
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicationRequest(Request arg0) {
|
public boolean isApplicationRequest(Request request) {
|
||||||
logger.debug("isApplicationRequest ");
|
final String uri = request.requestURI().toString();
|
||||||
return true;
|
return uri.endsWith("/dmx");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(WebSocket socket, com.sun.grizzly.websockets.DataFrame frame) {
|
||||||
|
DMXControllerWebSocket ws = (DMXControllerWebSocket) socket;
|
||||||
|
Mixer.getInstance().removeListener(ws);
|
||||||
|
logger.debug("removed websocket");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(WebSocket socket, String text) {
|
public void onMessage(WebSocket socket, String text) {
|
||||||
|
|
||||||
Mixer mixer = Mixer.getInstance();
|
Mixer mixer = Mixer.getInstance();
|
||||||
|
|
||||||
logger.debug("got message: " + text);
|
|
||||||
|
|
||||||
if(text.startsWith("channel:")) {
|
if(text.startsWith("channel:")) {
|
||||||
text = text.substring(text.indexOf(":")+1);
|
text = text.substring(text.indexOf(":")+1);
|
||||||
String[] parts = text.split("=");
|
String[] parts = text.split("=");
|
||||||
|
@ -42,13 +48,9 @@ public class DMXControllerApplication extends WebSocketApplication {
|
||||||
|
|
||||||
|
|
||||||
// for (final WebSocket webSocket : getWebSockets()) {
|
// for (final WebSocket webSocket : getWebSockets()) {
|
||||||
// try {
|
// DMXControllerWebSocket ws = (DMXControllerWebSocket) webSocket;
|
||||||
// // send data to all connected clients (including caller)
|
//
|
||||||
// webSocket.send(data);
|
//
|
||||||
// } catch (IOException e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// webSocket.close();
|
|
||||||
// }
|
|
||||||
// }
|
// }
|
||||||
//super.onMessage(socket, text);
|
//super.onMessage(socket, text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,39 @@
|
||||||
package de.ctdo.websocket;
|
package de.ctdo.websocket;
|
||||||
|
|
||||||
|
import net.sf.json.JSONArray;
|
||||||
|
import net.sf.json.JSONObject;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.sun.grizzly.websockets.DefaultWebSocket;
|
import com.sun.grizzly.websockets.DefaultWebSocket;
|
||||||
import com.sun.grizzly.websockets.ProtocolHandler;
|
import com.sun.grizzly.websockets.ProtocolHandler;
|
||||||
import com.sun.grizzly.websockets.WebSocketListener;
|
import com.sun.grizzly.websockets.WebSocketListener;
|
||||||
|
|
||||||
|
import de.ctdo.dmx.DMXDataChangedListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ein DMXControllerWebSocket gehoert immer zu einem Browserfenster/Tab
|
* Ein DMXControllerWebSocket gehoert immer zu einem Browserfenster/Tab
|
||||||
* @author lucas
|
* @author lucas
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DMXControllerWebSocket extends DefaultWebSocket {
|
public class DMXControllerWebSocket extends DefaultWebSocket implements DMXDataChangedListener {
|
||||||
|
|
||||||
|
Logger logger = LoggerFactory.getLogger(DMXControllerWebSocket.class);
|
||||||
|
|
||||||
public DMXControllerWebSocket(ProtocolHandler protocolHandler, WebSocketListener[] listeners) {
|
public DMXControllerWebSocket(ProtocolHandler protocolHandler, WebSocketListener[] listeners) {
|
||||||
super(protocolHandler, listeners);
|
super(protocolHandler, listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void DMXDataChanged(int[] dmx512data) {
|
||||||
|
|
||||||
|
JSONArray arr = JSONArray.fromObject(dmx512data);
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("dmx512values", arr);
|
||||||
|
|
||||||
|
send(obj.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,32 @@
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var ws;
|
var ws;
|
||||||
|
var dmxData;
|
||||||
|
|
||||||
$(document).ready(
|
$(document).ready(
|
||||||
function() {
|
function() {
|
||||||
|
|
||||||
ws = new MozWebSocket("ws://localhost:8080/bunti_server/dmx");
|
ws = new MozWebSocket("ws://localhost:8080/bunti_server/dmx");
|
||||||
//ws = new MozWebSocket("ws://localhost:8080/grizzly-websockets-chat/chat");
|
//ws = new MozWebSocket("ws://localhost:8080/grizzly-websockets-chat/chat");
|
||||||
|
|
||||||
ws.onmessage = function (message) {
|
ws.onmessage = function (message) {
|
||||||
$("#messages").append("<p>" + message.data + "</p>");
|
//$("#messages").append("<p>" + message.data + "</p>");
|
||||||
|
|
||||||
|
var obj = jQuery.parseJSON(message.data);
|
||||||
|
|
||||||
|
if( obj.dmx512values != null) {
|
||||||
|
dmxData = obj.dmx512values;
|
||||||
|
|
||||||
|
// das direkt zu machen ist evtl etwas unklug, da das sliden des sliders im
|
||||||
|
// gleichen browser dann hier zu ner aenderung fuehrt und der slider dann
|
||||||
|
// ruckelt. Aber es tut :D
|
||||||
|
$("#slider1").slider("value", dmxData[1]);
|
||||||
|
$("#slider2").slider("value", dmxData[2]);
|
||||||
|
$("#slider3").slider("value", dmxData[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onopen = function () {
|
ws.onopen = function () {
|
||||||
|
@ -42,17 +60,39 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
$("#slider").slider({ slide: function(event, ui) {
|
$("#slider1").slider({ min: 0, max: 255, slide: function(event, ui) {
|
||||||
ws.send("channel:2=" + ui.value);
|
ws.send("channel:2=" + ui.value);
|
||||||
|
ws.send("channel:7=" + ui.value);
|
||||||
|
ws.send("channel:12=" + ui.value);
|
||||||
|
ws.send("channel:17=" + ui.value);
|
||||||
|
} });
|
||||||
|
});
|
||||||
|
$(function() {
|
||||||
|
$("#slider2").slider({ min: 0, max: 255, slide: function(event, ui) {
|
||||||
|
ws.send("channel:3=" + ui.value);
|
||||||
|
ws.send("channel:8=" + ui.value);
|
||||||
|
ws.send("channel:13=" + ui.value);
|
||||||
|
ws.send("channel:18=" + ui.value);
|
||||||
|
} });
|
||||||
|
});
|
||||||
|
$(function() {
|
||||||
|
$("#slider3").slider({ min: 0, max: 255, slide: function(event, ui) {
|
||||||
|
ws.send("channel:4=" + ui.value);
|
||||||
|
ws.send("channel:9=" + ui.value);
|
||||||
|
ws.send("channel:14=" + ui.value);
|
||||||
|
ws.send("channel:19=" + ui.value);
|
||||||
} });
|
} });
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="demo">
|
<div class="demo">
|
||||||
<div id="slider"></div>
|
<div id="slider1" style="width: 300px"></div>
|
||||||
|
<div id="slider2" style="width: 300px; margin-top: 10px"></div>
|
||||||
|
<div id="slider3" style="width: 300px; margin-top: 10px"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="messages"></div>
|
<div id="messages"></div>
|
||||||
|
<input type="button" onclick="javascript:alert(dmx512values);" value="Bla" />
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue