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