00001 package edu.stanford.hci.r3.pen.streaming;
00002
00003 import java.io.BufferedReader;
00004 import java.io.IOException;
00005 import java.io.InputStream;
00006 import java.io.InputStreamReader;
00007 import java.net.InetAddress;
00008 import java.net.Socket;
00009 import java.net.SocketException;
00010 import java.net.UnknownHostException;
00011 import java.util.ArrayList;
00012 import java.util.Collections;
00013 import java.util.List;
00014
00015 import com.thoughtworks.xstream.XStream;
00016
00017 import edu.stanford.hci.r3.pen.PenSample;
00018 import edu.stanford.hci.r3.pen.streaming.listeners.PenListener;
00019 import edu.stanford.hci.r3.util.DebugUtils;
00020 import edu.stanford.hci.r3.util.networking.ClientServerType;
00021
00039 public class PenClient {
00040
00041 private Socket clientSocket;
00042
00043 private ClientServerType clientType;
00044
00045 private boolean exitFlag = false;
00046
00050 private List<PenListener> listeners = Collections
00051 .synchronizedList(new ArrayList<PenListener>());
00052
00056 private String machineName;
00057
00058 private int portNumber;
00059
00060 private Thread socketListenerThread;
00061
00067 public PenClient(String serverName, int port, ClientServerType type) {
00068 machineName = serverName;
00069 portNumber = port;
00070 clientType = type;
00071 }
00072
00077 public synchronized boolean addPenListener(PenListener penListener) {
00078 return listeners.add(penListener);
00079 }
00080
00084 public void connect() {
00085 socketListenerThread = getSocketListenerThreadBasedOnClientType();
00086 socketListenerThread.start();
00087 }
00088
00092 public synchronized void disconnect() {
00093 exitFlag = true;
00094 try {
00095 if (clientSocket != null) {
00096 clientSocket.close();
00097 }
00098 } catch (IOException e) {
00099 e.printStackTrace();
00100 }
00101 }
00102
00106 private Thread getSocketListenerThreadBasedOnClientType() {
00107
00108 if (clientType == ClientServerType.JAVA) {
00109 return new Thread(new Runnable() {
00110
00111 boolean penIsDown = false;
00112
00113 public void run() {
00114 try {
00115 final BufferedReader br = setupSocketAndReader();
00116 String line = null;
00117
00118 final XStream xml = new XStream();
00119
00120 while ((line = br.readLine()) != null) {
00121
00122
00123
00124 final PenSample sample = (PenSample) xml.fromXML(line);
00125 final boolean penIsUp = sample.isPenUp();
00126
00127
00128 if (!penIsDown && !penIsUp) {
00129 penIsDown = true;
00130 notifyListenersOfPenDown(sample);
00131 } else if (penIsUp) {
00132 penIsDown = false;
00133 notifyListenersOfPenUp(sample);
00134 } else {
00135
00136
00137
00138
00139
00140
00141
00142 if (penIsDown) {
00143 notifyListenersOfPenSample(sample);
00144 }
00145 }
00146
00147 if (exitFlag) {
00148 break;
00149 }
00150 }
00151 } catch (UnknownHostException e) {
00152 e.printStackTrace();
00153 } catch (SocketException se) {
00154 if (se.getMessage().contains("socket closed")) {
00155 DebugUtils.println("Pen Client's Socket is now closed...");
00156 }
00157 } catch (IOException e) {
00158 e.printStackTrace();
00159 }
00160 }
00161
00162 });
00163 } else {
00164 return new Thread(new Runnable() {
00165 public void run() {
00166 try {
00167 final BufferedReader br = setupSocketAndReader();
00168 String line = null;
00169 while ((line = br.readLine()) != null) {
00170
00171
00172
00173
00174
00175 System.out.println(line);
00176
00177 if (exitFlag) {
00178 break;
00179 }
00180 }
00181 } catch (UnknownHostException e) {
00182 e.printStackTrace();
00183 } catch (IOException e) {
00184 e.printStackTrace();
00185 }
00186 }
00187 });
00188 }
00189 }
00190
00194 private synchronized void notifyListenersOfPenDown(final PenSample sample) {
00195 for (PenListener pl : listeners) {
00196 pl.penDown(sample);
00197 }
00198 }
00199
00203 private synchronized void notifyListenersOfPenSample(final PenSample sample) {
00204 for (PenListener pl : listeners) {
00205 pl.sample(sample);
00206 }
00207 }
00208
00212 private synchronized void notifyListenersOfPenUp(final PenSample sample) {
00213 for (PenListener pl : listeners) {
00214 pl.penUp(sample);
00215 }
00216 }
00217
00224 public synchronized boolean removePenListener(PenListener penListener) {
00225 return listeners.remove(penListener);
00226 }
00227
00235 private BufferedReader setupSocketAndReader() throws UnknownHostException, IOException {
00236 DebugUtils.println("Trying to connect to " + machineName + ":" + portNumber);
00237 final InetAddress addr = InetAddress.getByName(machineName);
00238 final String hostName = addr.getCanonicalHostName();
00239 DebugUtils.println("The resolved host name of this pen is: " + hostName);
00240
00241 clientSocket = new Socket(machineName, portNumber);
00242 final InputStream inputStream = clientSocket.getInputStream();
00243 final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
00244 return br;
00245 }
00246 }