]> code.citadel.org Git - citadel.git/blob - webcit/static/wcCitServer.java
* Replaced the Java chat with a new system based on IFRAME's and JavaScript
[citadel.git] / webcit / static / wcCitServer.java
1 /*
2  * wcCitServer.java
3  *
4  * This module handles the tasks involving establishing a connection to a
5  * Citadel/UX server and moving data across the connection.  It also handles
6  * server "keepalives", the dispatching of "express messages", the 
7  * registration & termination of multiple threads, and a semaphore mechanism
8  * to prevent multiple threads from executing server commands at the same
9  * time.
10  */
11
12 import java.net.*;
13 import java.io.*;
14 import java.util.*;
15
16 /*
17  * We send 'keepalive' commands (actually just a NOOP) to the server every
18  * fifteen seconds, as a separate thread.  This prevents the server session
19  * from timing out, and also allows the client to be notified of any incoming
20  * express messages if the user isn't doing anything.
21  */
22 class wcKeepAlive extends Thread {
23
24         wcCitServer serv;       /* Pointer to server connection class */
25         boolean FullKeepAlives; /* TRUE for full keepalives, FALSE for half keepalives */
26
27          wcKeepAlive() {
28         } public void PointToServer(wcCitServer which_serv,
29                                     boolean WhatKindOfKeepAlives) {
30                 serv = which_serv;
31                 serv.AddClientThread(this);
32                 FullKeepAlives = WhatKindOfKeepAlives;
33         }
34
35         public void run() {
36                 String buf;
37                 while (true) {
38
39                         /* Sleep for sixty seconds between keepalives. */
40                         try {
41                                 sleep(60000);
42                         }
43                         catch(InterruptedException e) {
44                         }
45                         /* Full keepalives - send a NOOP, wait for a reply, then retrieve
46                          * express messages if the server said there are any.
47                          */
48                         if (FullKeepAlives) {
49                                 buf = serv.ServTrans("NOOP") + "    ";
50                         }
51
52                         /* Half keepalives - blindly send a NOOP and we're done. */
53                         else {
54                                 serv.ServPuts("NOOP");
55                         }
56
57                 }
58         }
59
60 }
61
62
63
64 /*
65  * the wcCitServer class handles communication with the server.
66  */
67 public class wcCitServer {
68         int connected = 0;
69         DataOutputStream ofp;
70         DataInputStream ifp;
71         Socket sock;
72         String TransBuf;
73         wcKeepAlive ka;
74         boolean in_trans = false;
75         Vector ClientThreads = new Vector();
76         Vector ServerInfo = new Vector();
77         String PrimaryServerHost;
78         int PrimaryServerPort;
79         String PrimaryServerUser;
80         String PrimaryServerPassword;
81
82         public void SetTransBuf(String bufstring) {
83                 TransBuf = bufstring;
84         } public String GetTransBuf() {
85                 return TransBuf;
86         }
87
88 /* attach to the server */
89         private void BuildConnection(String ServerHost, int ServerPort,
90                                      boolean WhichKA) {
91
92                 String buf;
93
94                 try {
95                         sock = new Socket(ServerHost, ServerPort);
96                         ofp = new DataOutputStream(sock.getOutputStream());
97                         ifp = new DataInputStream(sock.getInputStream());
98                 }
99                 catch(UnknownHostException e) {
100                         System.out.println(e);
101                 }
102                 catch(IOException e) {
103                         System.out.println(e);
104                 }
105
106                 /* Connection established.  At this point, this function
107                  * has the server connection all to itself, so we can do
108                  * whatever we want with it. */
109
110                 /* Get the 'server ready' message */
111                 buf = ServGets();
112
113                 /* Identify the client software to the server */
114                 ServTrans("IDEN 0|5|001|Cit/UX Java Client|");
115
116                 /* Download various information about the server */
117                 SetTransBuf("");
118                 buf = ServTrans("INFO");
119                 StringTokenizer InfoST =
120                     new StringTokenizer(TransBuf, "\n");
121                 while (InfoST.hasMoreTokens()) {
122                         ServerInfo.addElement(InfoST.nextToken());
123                 }
124
125
126                 /* At this point, all server accesses must cooperate with
127                  * server accesses from other threads by using the BeginTrans
128                  * and EndTrans semaphore mechanism.
129                  */
130                 ka = new wcKeepAlive();
131                 ka.PointToServer(this, WhichKA);
132                 ka.start();
133
134         }
135
136
137 /*
138  * Attach to server command for the primary socket
139  */
140         public void AttachToServer(String ServerHost, int ServerPort) {
141
142                 /* Connect to the server */
143 /* NOTE ... we've changed the primary connection keepalives to HALF because we're using the
144  * primary connection to jump right into a chat window.
145  */
146                 BuildConnection(ServerHost, ServerPort, false);
147
148                 /* And remember where we connected to, in case we have to
149                  * build any piggyback connections later on.
150                  */
151                 PrimaryServerHost = ServerHost;
152                 PrimaryServerPort = ServerPort;
153         }
154
155
156 /* 
157  * Learn info about the primary connection for setting up piggybacks
158  */
159         public String GetServerHost() {
160                 return PrimaryServerHost;
161         }
162
163         public int GetServerPort() {
164                 return PrimaryServerPort;
165         }
166
167
168 /*
169  * Set up a piggyback connection
170  */
171         public void Piggyback(wcCitServer PrimaryServ,
172                               boolean KeepAliveType) {
173                 PrimaryServerHost = PrimaryServ.GetServerHost();
174                 PrimaryServerPort = PrimaryServ.GetServerPort();
175                 PrimaryServerUser = PrimaryServ.GetUserName();
176                 PrimaryServerPassword = PrimaryServ.GetPassword();
177                 BuildConnection(PrimaryServerHost, PrimaryServerPort,
178                                 KeepAliveType);
179
180         }
181
182
183
184 /* return info about the site we're currently connected to */
185         public String ServInfo(int index) {
186                 String retbuf;
187                 if (index >= ServerInfo.size()) {
188                         return ("");
189                 } else {
190                         retbuf = ServerInfo.elementAt(index).toString();
191                         return (retbuf);
192                 }
193         }
194
195
196 /* read a line from the server */
197         public String ServGets() {
198
199                 String buf = "";
200
201                 try {
202                         buf = ifp.readLine();
203                 }
204                 catch(IOException e) {
205                         System.out.println(e);
206                 }
207                 return buf;
208         }
209
210
211 /* write a line to the server */
212         public void ServPuts(String buf) {
213
214                 try {
215                         ofp.writeBytes(buf + "\n");
216                 }
217                 catch(IOException e) {
218                         System.out.println(e);
219                 }
220         }
221
222
223 /* lock the server connection so other threads don't screw us up */
224         public synchronized void BeginTrans() {
225                 while (in_trans) {
226                         try {
227                                 System.out.println("-sleeping-");       /* trace */
228                                 Thread.sleep(100);
229                         }
230                         catch(InterruptedException e) {
231                         }
232                 }
233
234                 in_trans = true;
235         }
236
237 /* release the lock */
238         public void EndTrans() {
239                 in_trans = false;
240         }
241
242
243 /* perform an autonomous server transaction */
244         public String ServTrans(String ServCmd) {
245                 String buf;
246                 BeginTrans();
247                 buf = DataTrans(ServCmd);
248                 EndTrans();
249                 return buf;
250         }
251
252 /* perform a non-autonomous server transaction */
253         public String DataTrans(String ServCmd) {
254                 String buf = "";
255                 String inbuf = "";
256                 String expbuf = "";
257
258                 /* perform the transaction */
259
260                 System.out.println(">" + ServCmd);      /* trace */
261                 ServPuts(ServCmd);
262                 buf = ServGets();
263                 System.out.println("<" + buf);  /* trace */
264
265                 try {
266                         if (buf.startsWith("4")) {
267                                 ofp.writeBytes(TransBuf);
268                                 if (!TransBuf.endsWith("\n")) {
269                                         ofp.writeBytes("\n");
270                                 }
271                                 ofp.writeBytes("000");
272                                 TransBuf = "";
273                         }
274
275                         if (buf.startsWith("1")) {
276                                 TransBuf = "";
277                                 inbuf = "";
278                                 do {
279                                         inbuf = ServGets();
280                                         if (!TransBuf.equals("")) {
281                                                 TransBuf = TransBuf + "\n";
282                                         }
283                                         if (!inbuf.equals("000")) {
284                                                 TransBuf =
285                                                     TransBuf + inbuf;
286                                         }
287                                 } while (!inbuf.equals("000"));
288                         }
289                 }
290                 catch(IOException e) {
291                         System.out.println(e);
292                 }
293
294                 return (buf);
295         }
296
297         public void AddClientThread(Thread ct) {
298                 ClientThreads.addElement(ct);
299                 System.out.println("--new thread registered--");
300         }
301
302         public void RemoveClientThread(Thread ct) {
303                 ClientThreads.removeElement(ct);
304                 System.out.println("--thread removed--");
305         }
306
307
308
309         /* The following four functions take care of keeping track of the
310          * user name and password being used on the primary server connection
311          * in case we want to use them for a piggyback connection.
312          */
313         public void SetUserName(String U) {
314                 PrimaryServerUser = U;
315         }
316
317         public void SetPassword(String P) {
318                 PrimaryServerPassword = P;
319         }
320
321         public String GetUserName() {
322                 return PrimaryServerUser;
323         }
324
325         public String GetPassword() {
326                 return PrimaryServerPassword;
327         }
328
329
330
331 }