package com.jaivox.synthesizer.freetts; import java.net.Socket; import java.util.*; import com.jaivox.agent.*; import com.jaivox.util.Log; /** * SynthServer is an synthesizer server. In a typical application, this * server communicates with an interpreter and gets requests to speak. * This package uses Free Tts. See comments in Synthesizer for the * correct way to specify the CLASSPATH to use freetts.jar (the location * of the jar file is used by freetts to locate some other files, thus * you need to set that path explicity in the CLASSPATH.) */ public class SynthServer extends Server implements Runnable { int waitTime = 5000; String basedir; Properties kv; Synthesizer Synth; /** * The Sythensizer may need information from some files. * Here the server sets some variables that can be accessed by * the SynthResponder when creating an Synthesizer class @param name @param port @param base @param kv Properties for the Synthpreter */ public SynthServer (String name, int port, String base, Properties pp) { super (name, port); basedir = base; kv = pp; Synth = new Synthesizer (base, kv); } /** * Creates an SynthServer that listens on the designated port @param port socket listens on this port */ public SynthServer (int port) { super (port); } /** * Crates an SynthServer with a specific name, that listens at * the specified port @param name Name of the server (used in messages) @param port socket listens on this port */ public SynthServer (String name, int port) { super (name, port); } public void run () { try { while (true) { Socket link = server.accept (); int count = getIdCount (); String id = Name+"_"+getIdCount (); setIdCount (count+1); SynthResponder r = new SynthResponder (basedir, kv, Synth); SynthSession ias = new SynthSession (id, this, link, r); addSession (ias); Log.info ("Added client "+ias.getSid ()); } } catch (Exception e) { e.printStackTrace (); Log.severe (Name+" "+e.toString ()); } } /** * Execute agent-based commands to connect, disconnect and perform * other actions @param command */ public void execute (String command) { try { Vector <String> tokens = new Vector <String> (); StringTokenizer st = new StringTokenizer (command); while (st.hasMoreTokens ()) { String token = st.nextToken (); tokens.add (token); } int ntok = tokens.size (); if (command.startsWith ("connect")) { if (ntok != 3) { Log.warning ("Syntax: connect host port"); return; } String host = tokens.elementAt (1); int port = Integer.parseInt (tokens.elementAt (2)); Socket link = new Socket (host, port); int count = sessionCount (); String id = Name+"_"+count; SynthResponder rtest = new SynthResponder (basedir, kv, Synth); SynthSession ias = new SynthSession (id, this, link, rtest); rtest.setOwner (ias); addSession (ias); Log.info ("Made connection client id "+id); } else if (command.startsWith ("disconnect")) { if (ntok != 2) { Log.warning ("Sytax: disconnect sessionid"); return; } String id = tokens.elementAt (1); Session ias = findSession (id); if (ias == null) { Log.warning ("No session with id "+id); return; } // send a terminate message to the session Log.info ("disconnecting from "+id); String req = "{action: JviaTerminate, from: "+getId ()+", to: "+ias.getSid (); req += ", message: JviaTerminate}"; ias.outbuffer = req; sleep (waitTime); ias.terminate (); // then terminate it } else if (command.startsWith ("send")) { // write it to the outstream of the session? if (ntok < 3) { Log.warning ("Sytax: send sessionid message"); return; } String id = tokens.elementAt (1); Session ias = findSession (id); if (ias == null) { Log.warning ("No session with id "+id); return; } StringBuffer sb = new StringBuffer (); sb.append (tokens.elementAt (2)); for (int i=3; i<ntok; i++) { sb.append (' '); sb.append (tokens.elementAt (i)); } String message = new String (sb); ias.outbuffer = message; // Log.fine ("sending \""+message+"\" to "+id); if (message.equals (TestResponder.terminateRequest)) { sleep (waitTime); ias.terminate (); } } else if (command.equals ("terminate")) { // terminate all clients, then stop Vector <Session> clients = getClients (); for (int i=0; i<clients.size (); i++) { Session ias = clients.elementAt (i); String req = "{action: JviaTerminate, from: "+getId ()+", to: "+ias.getSid (); req += ", message: JviaTerminate}"; ias.outbuffer = req; sleep (waitTime); Log.info ("Terminating "+ias.getSid ()); ias.terminate (); } server.close (); interrupt (); return; } else { Log.warning ("illegal command: "+command); } } catch (Exception e) { Log.severe ("Synthserver: execute "+e.toString ()); } } /** * Execute a request with a reply @param command @return */ public String executeReply (String command) { try { Vector <String> tokens = new Vector <String> (); StringTokenizer st = new StringTokenizer (command); while (st.hasMoreTokens ()) { String token = st.nextToken (); tokens.add (token); } int ntok = tokens.size (); if (command.startsWith ("connect")) { if (ntok != 3) { Log.warning ("Syntax: connect host port"); return "Error: invalid syntax"; } String host = tokens.elementAt (1); int port = Integer.parseInt (tokens.elementAt (2)); Socket link = new Socket (host, port); int count = sessionCount (); String id = Name+"_"+count; SynthResponder rtest = new SynthResponder (); SynthSession ias = new SynthSession (id, this, link, rtest); rtest.setOwner (ias); addSession (ias); return ("OK: Made connection client id "+id); } else if (command.startsWith ("disconnect")) { if (ntok != 2) { return ("Error: Syntax: disconnect sessionid"); } String id = tokens.elementAt (1); Session ias = findSession (id); if (ias == null) { return ("Error: No session with id "+id); } // send a terminate message to the session Log.info ("disconnecting from "+id); String req = "{action: JviaTerminate, from: "+getId ()+", to: "+ias.getSid (); req += ", message: JviaTerminate}"; ias.outbuffer = req; sleep (waitTime); ias.terminate (); // then terminate it sleep (waitTime); return ("OK: Terminate requested."); } else if (command.startsWith ("send")) { // write it to the outstream of the session? if (ntok < 3) { Log.warning ("Error: Syntax: send sessionid message"); } String id = tokens.elementAt (1); Session ias = findSession (id); if (ias == null) { return ("Error: No session with id "+id); } StringBuffer sb = new StringBuffer (); sb.append (tokens.elementAt (2)); for (int i=3; i<ntok; i++) { sb.append (' '); sb.append (tokens.elementAt (i)); } String message = new String (sb); // String req = "{action: send, from: "+getId ()+", to: "+ias.getSid (); // req += ", message: "+message+"}"; // send a terminate message to the session ias.outbuffer = message; Log.fine ("sending \""+message+"\" to "+id); if (message.equals (TestResponder.terminateRequest)) { sleep (waitTime); ias.terminate (); sleep (waitTime); return ("OK: Terminate requested."); } else return ("OK: Message sent:"+message); } else if (command.equals ("terminate")) { // terminate all clients, then stop Vector <Session> clients = getClients (); for (int i=0; i<clients.size (); i++) { Session ias = clients.elementAt (i); String req = "{action: JviaTerminate, from: "+getId ()+", to: "+ias.getSid (); req += ", message: JviaTerminate}"; ias.outbuffer = req; sleep (waitTime); Log.info ("Terminating "+ias.getSid ()); ias.terminate (); } server.close (); interrupt (); return ("OK: terminated."); } else { return ("Error: illegal command: "+command); } } catch (Exception e) { Log.severe ("SynthServer:executeReply "+e.toString ()); return ("Error: "+e.toString ()); } } /** * Returns a pointer to the Synthesizer used by this agent */ public Synthesizer getSynthesizer () { return Synth; } /** * Sets a particular synthesizer to be used by this agent. @param synth */ public void setSynthesizer (Synthesizer synth) { Synth = synth; } }