Project

General

Profile

2967_1.txt

Sergey Ivanovskiy, 02/20/2016 01:18 PM

Download (27.7 KB)

 
1
=== modified file 'src/com/goldencode/p2j/main/WebClientBuilder.java'
2
--- src/com/goldencode/p2j/main/WebClientBuilder.java	2016-02-05 10:17:52 +0000
3
+++ src/com/goldencode/p2j/main/WebClientBuilder.java	2016-02-20 18:09:00 +0000
4
@@ -15,6 +15,7 @@
5
 ** 004 GES 20150312 Added support for the GUI web client.
6
 ** 005 GES 20150710 Modified/added configuration processing for GUI, clipboard flag is ChUI-only.
7
 ** 006 CA  20160205 Changed to use ServerKeyStore.getStore().
8
+**     SBI 20160220 Added maxBinaryMessage, maxTextMessage, maxIdleTime websocket's parameters. 
9
 */
10
 
11
 package com.goldencode.p2j.main;
12
@@ -96,10 +97,14 @@
13
          command.add("client:chui:fontsize=" + options.get("fontsize"));
14
          command.add("client:web:clipboard=" + options.get("clipboard"));
15
       }
16
-      
17
+      // Common Websocket parameters:
18
       command.add("client:web:socketTimeout=" + options.get("webSocketTimeout"));
19
       command.add("client:web:watchdogTimeout=" + options.get("watchdogTimeout"));
20
       
21
+      command.add("client:web:maxBinaryMessage=" + options.get("maxBinaryMessage"));
22
+      command.add("client:web:maxTextMessage="   + options.get("maxTextMessage"));
23
+      command.add("client:web:maxIdleTime="      + options.get("maxIdleTime"));
24
+      
25
       if (options.get("port") != null)
26
       {
27
          command.add("client:web:port=" + options.get("port"));
28

    
29
=== modified file 'src/com/goldencode/p2j/main/WebClientBuilderOptions.java'
30
--- src/com/goldencode/p2j/main/WebClientBuilderOptions.java	2015-08-07 20:47:38 +0000
31
+++ src/com/goldencode/p2j/main/WebClientBuilderOptions.java	2016-02-20 18:09:36 +0000
32
@@ -13,6 +13,7 @@
33
 ** 002 MAG 20140711 Enable/Disable clipboard.
34
 ** 003 GES 20150310 Made this class generic for web clients, not just for ChUI web clients.
35
 ** 004 GES 20150717 Added some GUI configuration values.
36
+** 005 SBI 20160220 Added maxBinaryMessage, maxTextMessage, maxIdleTime websocket's parameters
37
 */
38
 
39
 package com.goldencode.p2j.main;
40
@@ -20,7 +21,6 @@
41
 import java.util.*;
42
 
43
 import com.goldencode.p2j.net.*;
44
-import com.goldencode.p2j.ui.client.*;
45
 import com.goldencode.p2j.ui.client.chui.driver.*;
46
 
47
 /**
48
@@ -35,6 +35,15 @@
49
 {   
50
    /** Directory node name in which our configuration can be found. */
51
    public static final String DIRECTORY_NODE_ID = "webClient";
52
+   
53
+   /** The default maximal binary message size excepted by the configured websocket */
54
+   private static final int MAX_BINARY_MESSAGE_SIZE = 32768;
55
+   
56
+   /** The default maximal text message size excepted by the configured websocket */
57
+   private static final int MAX_TEXT_MESSAGE_SIZE = 4096;
58
+   
59
+   /** The default maximal idle time of the configured websocket */
60
+   private static final int MAX_IDLE_TIMEOUT = 90000;
61
 
62
    /**
63
     * Singleton instance. Not set as final to allow it to be invalidated (in case these
64
@@ -150,6 +159,12 @@
65
       fontsize   = getNode(DIRECTORY_NODE_ID, "fontsize", fontsize);
66
       stimeout   = getNode(DIRECTORY_NODE_ID, "webSocketTimeout", (int) stimeout);
67
       wtimeout   = getNode(DIRECTORY_NODE_ID, "watchdogTimeout",  (int) wtimeout);
68
+      
69
+      // Common websocket parameters:
70
+      int maxBinaryMessage = getNode(DIRECTORY_NODE_ID, "maxBinaryMessage", MAX_BINARY_MESSAGE_SIZE);
71
+      int maxTextMessage   = getNode(DIRECTORY_NODE_ID, "maxTextMessage", MAX_TEXT_MESSAGE_SIZE);
72
+      int maxIdleTime      = getNode(DIRECTORY_NODE_ID, "maxIdleTime", MAX_IDLE_TIMEOUT);
73
+      
74
       port       = getNode(DIRECTORY_NODE_ID, "port", port);
75
       host       = getNode(DIRECTORY_NODE_ID, "host", host);
76
       clipboard  = getNode(DIRECTORY_NODE_ID, "clipboard", true);
77
@@ -171,5 +186,8 @@
78
       options.put("host", host);
79
       options.put("clipboard", clipboard ? "true" : "false");
80
       options.put("taskbar", taskbar ? "true" : "false");
81
+      options.put("maxBinaryMessage", String.valueOf(maxBinaryMessage));
82
+      options.put("maxTextMessage", String.valueOf(maxTextMessage));
83
+      options.put("maxIdleTime", String.valueOf(maxIdleTime));
84
    }
85
 }
86

    
87
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/WebClientMessageTypes.java'
88
--- src/com/goldencode/p2j/ui/client/driver/web/WebClientMessageTypes.java	2016-02-03 11:21:56 +0000
89
+++ src/com/goldencode/p2j/ui/client/driver/web/WebClientMessageTypes.java	2016-02-20 16:11:14 +0000
90
@@ -19,6 +19,7 @@
91
 **                  and z-order operations.
92
 ** 005 CA  20151024 Added support for WINDOW:SENSITIVE attribute.
93
 ** 006 CA  20160203 Added hash management operations.
94
+**     SBI 20160220 Added MSG_PARTIAL, MSG_FILE_UPLOAD
95
 */
96
 
97
 package com.goldencode.p2j.ui.client.driver.web;
98
@@ -183,4 +184,10 @@
99
 
100
    /** Inform the javascript side to remove the list of expired hashes. */
101
    public static final byte MSG_REMOVE_EXPIRED_HASH = (byte) 0xA0;
102
+
103
+   /** Wraps the large message from the client to the sequence of this partial type messages. */
104
+   public static final byte MSG_PARTIAL = (byte) 0xFE;
105
+
106
+   /** File upload message. */
107
+   public static final byte MSG_FILE_UPLOAD = (byte) 0xFD;
108
 }
109

    
110
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/WebClientProtocol.java'
111
--- src/com/goldencode/p2j/ui/client/driver/web/WebClientProtocol.java	2016-02-03 11:21:56 +0000
112
+++ src/com/goldencode/p2j/ui/client/driver/web/WebClientProtocol.java	2016-02-20 16:50:14 +0000
113
@@ -19,17 +19,23 @@
114
 **                  message result.
115
 ** 005 CA  20160203 Fixed deadlock for receivedMessages - it must lock on the "lock" field, as
116
 **                  this object is used for all sock operations (including key reading).
117
+**     SBI 20160220 Added MSG_PARTIAL and MSG_FILE_UPLOAD.
118
 */
119
 
120
 package com.goldencode.p2j.ui.client.driver.web;
121
 
122
+import java.io.*;
123
 import java.nio.*;
124
+import java.nio.channels.*;
125
+import java.nio.file.*;
126
+import java.nio.file.attribute.*;
127
 import java.util.*;
128
 import java.util.concurrent.*;
129
 
130
 import org.eclipse.jetty.websocket.api.*;
131
 import org.eclipse.jetty.websocket.api.annotations.*;
132
 
133
+
134
 /**
135
  * Implements the WebSockets protocol to drive communications with a JavaScript web client.
136
  * <p>
137
@@ -144,7 +150,7 @@
138
  * 
139
  */
140
 @SuppressWarnings("serial")
141
-@WebSocket(maxIdleTime = 900000, maxTextMessageSize = 4096, maxBinaryMessageSize = 32768)
142
+@WebSocket
143
 public class WebClientProtocol
144
 implements WebClientMessageTypes
145
 {
146
@@ -174,7 +180,48 @@
147
     * "synchronous" approach must call {@link #waitForResult} for the expected operation.
148
     */
149
    private Map<Integer, Object> receivedMessages = new HashMap<>();
150
-         
151
+   
152
+   /** Partial messages are mapped to open file channels. */
153
+   private Map<Integer, FileChannel> partialMessages = new HashMap<>();
154
+   
155
+   /** The directory to save partial messages to the corresponding temporary file */
156
+   private Path tmpDir;
157
+   
158
+   /** The options used to open file channels for created temporary files */
159
+   private static final StandardOpenOption[] TMP_FILE_OPTIONS
160
+      = new StandardOpenOption[]
161
+            {
162
+               StandardOpenOption.READ,
163
+               StandardOpenOption.WRITE,
164
+               StandardOpenOption.DELETE_ON_CLOSE
165
+            };
166
+   
167
+   /** The file permissions to create a new temporary file */
168
+   private static final Set<PosixFilePermission> NEW_TMP_FILE_PERMISSIONS;
169
+   
170
+   static
171
+   {
172
+      PosixFilePermission[] permissions
173
+         = new PosixFilePermission[]
174
+               {
175
+                  PosixFilePermission.OWNER_READ,
176
+                  PosixFilePermission.OWNER_WRITE
177
+               };
178
+      NEW_TMP_FILE_PERMISSIONS = new HashSet<PosixFilePermission>(Arrays.asList(permissions));
179
+   }
180
+   
181
+   /** The new created temporary file name should start from this string */
182
+   private static final String TMP_FILE_PREFIX = "msg";
183
+   
184
+   /** The new created temporary file extension */
185
+   private static final String TMP_FILE_EXT = ".tmp";
186
+   
187
+   /**
188
+    * Executes tasks to collect partial messages having the same id number to a one large
189
+    * binary message.
190
+    */
191
+   private final ExecutorService asynchIOExecutor = Executors.newSingleThreadExecutor();
192
+   
193
    /** Callbacks for delegated processing. */
194
    protected ClientProtocolHooks callbacks = null;
195
    
196
@@ -207,7 +254,14 @@
197
       this.callbacks = callbacks;
198
       this.timeout   = timeout;
199
       this.wdtimeout = wdtimeout;
200
-      
201
+      try
202
+      {
203
+         this.tmpDir = Files.createTempDirectory(null);
204
+      }
205
+      catch (IOException e)
206
+      {
207
+         e.printStackTrace();
208
+      }
209
       startWatchdog(wdtimeout);
210
    }
211
    
212
@@ -331,6 +385,98 @@
213
          paste(message, offset, length);
214
          handled = true;
215
       }
216
+      else if (length > 11 && message[offset] == MSG_PARTIAL)
217
+      {
218
+         // [MSG_PARTIAL_TYPE][MSG_ID][PARTIAL_STATUS][PAYLOAD_LENGTH][PAYLOAD_DATA]
219
+         // 1 + 4 + 1 + 4 + length(payload data) > 10 
220
+         final int msgId = readMessageInt32(message, offset + 1);
221
+         // PARTIAL_STATUS is 1 byte that equals 0 if it is the last message with MSG_ID or
222
+         // 1 if a next message with the same MSG_ID should follow this one.
223
+         final boolean isLast = message[offset + 5] == 0x0;
224
+         final int payloadLength = readMessageInt32(message, offset + 6);
225
+         final ByteBuffer payloadData = ByteBuffer.wrap(message, offset + 10, payloadLength);
226
+         FileChannel channel = partialMessages.get(msgId);
227
+         if (channel == null)
228
+         {
229
+            try
230
+            {
231
+               
232
+               Path channelPath = Files.createTempFile(tmpDir, TMP_FILE_PREFIX, TMP_FILE_EXT, 
233
+                        PosixFilePermissions.asFileAttribute(NEW_TMP_FILE_PERMISSIONS));
234
+               channel = FileChannel.open(channelPath, TMP_FILE_OPTIONS);
235
+               partialMessages.put(msgId, channel);
236
+            }
237
+            catch (IOException e)
238
+            {
239
+               // TODO how to log exceptions
240
+               // e.printStackTrace();
241
+            }
242
+         }
243
+         
244
+         if (channel != null && channel.isOpen())
245
+         {
246
+            asynchIOExecutor.submit(
247
+                     /**
248
+                      * The task that appends a new partial message to the already received
249
+                      * messages having the same id number (or belonging to the same packet
250
+                      * of messages).
251
+                      */
252
+                     new Runnable()
253
+                     {
254
+                        @Override
255
+                        public void run()
256
+                        {
257
+                           
258
+                           try
259
+                           {
260
+                              // Find a channel by id
261
+                              FileChannel channel = partialMessages.get(msgId);
262
+                              // Write a payload data
263
+                              channel.write(payloadData);
264
+                              if (isLast)
265
+                              {
266
+                                 // if message is the last message in this messages packet
267
+                                 // then read all gathered payload data and deliver it
268
+                                 // to the messages processor 
269
+                                 
270
+                                 int size = (int) channel.size();
271
+                                 ByteBuffer dst = ByteBuffer.allocate(size);
272
+                                 final int readedBytes = channel.read(dst, 0);
273
+                                 dst.flip();
274
+                                 
275
+                                 // close channel to dispose used resources
276
+                                 channel.close();
277
+                                 partialMessages.remove(msgId);
278
+                                 
279
+                                 if (readedBytes == size)
280
+                                 {
281
+                                    // deliver the large message to its processor
282
+                                    webWorker.post(new Runnable()
283
+                                    {
284
+                                       @Override
285
+                                       public void run()
286
+                                       {
287
+                                          processBinaryMessage(dst.array(), 0, readedBytes);
288
+                                       }
289
+                                    });
290
+                                 }
291
+                              }
292
+                           }
293
+                           catch (IOException e)
294
+                           {
295
+                              // TODO how to log exceptions
296
+                              // e.printStackTrace();
297
+                           }
298
+                        }
299
+            });
300
+         }
301
+         handled = true;
302
+      }
303
+      else if (length > 5 && message[offset] == MSG_FILE_UPLOAD)
304
+      {
305
+         // TODO : MSG_FILE_UPLOAD is wrapped by MSG_PARTIAL messages as payload data
306
+         handled = true;
307
+      }
308
       
309
       return handled;
310
    }
311

    
312
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/WebPageHandler.java'
313
--- src/com/goldencode/p2j/ui/client/driver/web/WebPageHandler.java	2015-08-07 20:47:38 +0000
314
+++ src/com/goldencode/p2j/ui/client/driver/web/WebPageHandler.java	2016-02-20 17:05:56 +0000
315
@@ -12,6 +12,8 @@
316
 ** 001 GES 20150312 Created initial version by moving code from the ChuiWebPageHandler and making
317
 **                  it more generic (to handle GUI too).
318
 ** 002 GES 20150717 Moved clipboard processing to ChUI-specific location.
319
+** 003 SBI 20160220 Added maxBinaryMessage parameter to the template file in order to deliver
320
+**                  its value to the JS client.
321
 */
322
 
323
 package com.goldencode.p2j.ui.client.driver.web;
324
@@ -145,10 +147,17 @@
325
       
326
       if (text.contains("${referrer}"))
327
       {
328
-         String referrer = config.getString("web", "referrer", "url", null);               
329
+         String referrer = config.getString("web", "referrer", "url", null);
330
          text = text.replace("${referrer}", referrer);
331
       }
332
       
333
+      if (text.contains("${maxBinaryMessage}"))
334
+      {
335
+         // configuration must provide the valid value of client:web:maxBinaryMessage
336
+         int maxBinaryMessage = config.getInt("client", "web", "maxBinaryMessage", 1024);
337
+         text = text.replace("${maxBinaryMessage}", String.valueOf(maxBinaryMessage));
338
+      }
339
+      
340
       return text;
341
    }
342
    
343

    
344
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/index.html'
345
--- src/com/goldencode/p2j/ui/client/driver/web/index.html	2015-12-17 20:00:50 +0000
346
+++ src/com/goldencode/p2j/ui/client/driver/web/index.html	2016-02-19 22:07:40 +0000
347
@@ -38,7 +38,7 @@
348
                'font' : {'name' : '${font.name}', 'size' : ${font.size}, 'color' : {'f' : '${font.color}', 'b' : '${font.background}'}},
349
                'cursor' : {'type' : 'solid', 'visible' : true, 'blinking' : false},
350
                'sound' : {'id' : 'beep', 'enabled' : true},
351
-               'socket' : {'url' : 'wss://' + window.location.host + '${context}/ajax'},
352
+               'socket' : {'url' : 'wss://' + window.location.host + '${context}/ajax', 'maxBinaryMessage' : ${maxBinaryMessage}},
353
                'page' : 'index.html',
354
                'clipboard' : {'enabled' : ${clipboard.enabled}, 'id' : 'clipboard', 'stroke' : true, 'input' : 'copy'},
355
                'taskbar' : {'enabled' : ${taskbar.enabled}},
356

    
357
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js'
358
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js	2016-02-16 20:45:37 +0000
359
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js	2016-02-20 17:36:01 +0000
360
@@ -41,7 +41,8 @@
361
 **     SBI 20160107 Supported new message with 0x9F id to test if the target font family is
362
 **                  available for the browser.
363
 **     CA  20160629 Added a drawing cache (and cache management, when the hash was expired by the
364
-*                   client-side).
365
+**                  client-side).
366
+**     SBI 20160202 Implemented MSG_PARTIAL.
367
 */
368
 
369
 "use strict";
370
@@ -66,6 +67,116 @@
371
    /** The count of the drawing operations. */
372
    var drawNo = 0;
373
 
374
+   /** The maximal size for binary messages that can be accepted by the websocket server. */ 
375
+   var maxBinaryMessage;
376
+   
377
+   /**
378
+    * The next unique message id.
379
+    */
380
+   var nextMsgId = 0;
381
+
382
+   /** The fast timer object */
383
+   var fastTimer = new FastTimer("https://" + window.location.host);
384
+   
385
+   /**
386
+    * The fast timer to execute tasks in the UI thread.
387
+    * 
388
+    * @param    {String} origin
389
+    *           The message origin is an URL that defines what messages are handled by this timer.
390
+    */
391
+   function FastTimer(origin)
392
+   {
393
+      var notification = "fast-timer-notification";
394
+      var targetOrigin = origin;
395
+      
396
+      /**
397
+       * The tasks queue to be performed by the fast timer. A task must have "execute" function
398
+       * as its public member.
399
+       */
400
+      var tasksQueue = [];
401
+      
402
+      /**
403
+       * Schedule a task to be executed by the fast timer.
404
+       * 
405
+       * @param    {Task} task
406
+       */
407
+      function scheduleTask(task)
408
+      {
409
+         tasksQueue.push(task);
410
+         window.postMessage(notification, targetOrigin);
411
+      }
412
+      
413
+      this.scheduleTask = scheduleTask;
414
+      
415
+      /**
416
+       * Executes the next task from the tasks queue as soon as a notification message is caught.
417
+       * 
418
+       * @param    {Event} event
419
+       *           A notification event that is handled by this fast timer
420
+       */
421
+      function executeTask(event)
422
+      {
423
+          if (event.source == window && event.data == notification)
424
+          {
425
+              event.stopPropagation();
426
+              if (tasksQueue.length > 0)
427
+              {
428
+                  var task = tasksQueue.shift();
429
+                  task.execute();
430
+              }
431
+          }
432
+      }
433
+      
434
+      window.addEventListener("message", executeTask, true);
435
+   };
436
+
437
+   /**
438
+    * Sends a large message via partial messages as payload data nested by MSG_PARTIAL messages.
439
+    * 
440
+    * @param    {Uint8Array} msg
441
+    *           The large source message that should be send by packets.
442
+    */
443
+   function sendMessageByPackets(msg)
444
+   {
445
+      var task = {position : 0, capacity : msg.byteLength, msg : msg};
446
+      task.msgId = nextMsgId;
447
+      nextMsgId++;
448
+      task.execute = function ()
449
+      {
450
+         var position = task.position;
451
+         var capacity = task.capacity;
452
+         var remaining = capacity - position;
453
+         
454
+         var payloadLength;
455
+         var isLast;
456
+         if (remaining >=  maxBinaryMessage - 10)
457
+         {
458
+            payloadLength = maxBinaryMessage - 10;
459
+            isLast = false;
460
+         }
461
+         else
462
+         {
463
+            payloadLength = remaining;
464
+            isLast = true;
465
+         }
466
+         var limit = position + payloadLength;
467
+         // send partial message
468
+         me.sendPartialMessage(task.msg, position, limit, payloadLength, task.msgId, isLast)
469
+         
470
+         position  = limit;
471
+         remaining = capacity - position;
472
+         task.position  = position;
473
+         task.remaining = remaining;
474
+         // if there are bytes to send, then schedule new task
475
+         if (remaining > 0)
476
+         {
477
+            fastTimer.scheduleTask(task);
478
+         }
479
+      };
480
+      
481
+      fastTimer.scheduleTask(task);
482
+   }
483
+
484
    /**
485
     * Send data.
486
     * 
487
@@ -75,7 +186,14 @@
488
    {
489
       if (connected) 
490
       {
491
-         ws.send(data);
492
+         if (data.byteLength <= maxBinaryMessage)
493
+         {
494
+            ws.send(data);
495
+         }
496
+         else
497
+         {
498
+            sendMessageByPackets(data);
499
+         }
500
       }
501
       else
502
       {
503
@@ -98,6 +216,38 @@
504
    };
505
    
506
    /**
507
+    * Send a partial message that wraps the payload data.
508
+    *
509
+    * @param    {Uint8Array} data
510
+    *           The large source message that should be send by packets.
511
+    * @param    {Number} position
512
+    *           It points to the first byte of the payload data.
513
+    * @param    {Number} limit
514
+    *           The upper barrier index of the payload data. T
515
+    * @param    {Number} payloadLength
516
+    *           The number of bytes to send starting from the given position.
517
+    * @param    {Number} msgId
518
+    *           The message id that identifies the large source message.
519
+    * @param    {Boolean} isLast
520
+    *           Indicates the last message in the packets to send.
521
+    */
522
+   me.sendPartialMessage = function(data, position, limit, payloadLength, msgId, isLast)
523
+   {
524
+      var msg = new Uint8Array(payloadLength + 10);
525
+      msg[0] = 0xFE;
526
+      me.writeInt32BinaryMessage(msg, 1, msgId);
527
+      msg[5] = isLast ? 0 : 1;
528
+      me.writeInt32BinaryMessage(msg, 6, payloadLength);
529
+      var i, j;
530
+      for(i = position, j = 10; i < limit; i++, j++)
531
+      {
532
+         msg[j] = data[i];
533
+      }
534
+      
535
+      me.send(msg);
536
+   };
537
+   
538
+   /**
539
     * Sends the window active event to the server.
540
     * 
541
     * @param    {Number} wid
542
@@ -455,6 +605,8 @@
543
    {      
544
       referrer = cfg.referrer;
545
       
546
+      maxBinaryMessage = cfg.socket.maxBinaryMessage
547
+      
548
       if ('WebSocket' in window)
549
       {
550
          ws = new WebSocket(cfg.socket.url);
551

    
552
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java'
553
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java	2016-02-16 20:45:37 +0000
554
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java	2016-02-19 20:25:02 +0000
555
@@ -63,7 +63,7 @@
556
  * is running during session establishment with the P2J server using logging no messages are 
557
  * written into the log and the application is blocked.
558
  */
559
-@WebSocket(maxIdleTime = 900000, maxTextMessageSize = 4096, maxBinaryMessageSize = 32768)
560
+@WebSocket
561
 public class GuiWebSocket
562
 extends WebClientProtocol
563
 {
564

    
565
=== modified file 'src/com/goldencode/p2j/web/GenericWebServer.java'
566
--- src/com/goldencode/p2j/web/GenericWebServer.java	2015-05-18 20:48:28 +0000
567
+++ src/com/goldencode/p2j/web/GenericWebServer.java	2016-02-20 18:09:39 +0000
568
@@ -12,6 +12,7 @@
569
 ** 001 MAG 20131105 First version based on jetty 9.1
570
 ** 002 MAG 20131129 Import server KeyStore.
571
 ** 003 AB  20150515 Removed configWsContext() and now directly use the handler collection.
572
+** 004 SBI 20160220 Changed to set the websocket parameters from the server provided configuration.
573
 */
574
 
575
 package com.goldencode.p2j.web;
576
@@ -232,7 +233,7 @@
577
     */
578
    public void addWebSocketHandler(String target, Class<?> webSocket)
579
    {
580
-      Handler wsHandler = new PojoWebSocketHandler(target, webSocket);
581
+      Handler wsHandler = new PojoWebSocketHandler(target, webSocket, new WebSocketConfig(config));
582
       handlerCollection.addHandler(wsHandler);
583
    }
584
 
585
@@ -246,7 +247,7 @@
586
     */
587
    public void addWebSocketHandler(String target, WebSocketCreator creator)
588
    {
589
-      Handler wsHandler = new PojoWebSocketHandler(target, creator);
590
+      Handler wsHandler = new PojoWebSocketHandler(target, creator, new WebSocketConfig(config));
591
       handlerCollection.addHandler(wsHandler);
592
    }
593
    
594
@@ -439,4 +440,5 @@
595
    {
596
       this.serverKeyStore = keyStore;
597
    }
598
+   
599
 }
600

    
601
=== modified file 'src/com/goldencode/p2j/web/PojoWebSocketHandler.java'
602
--- src/com/goldencode/p2j/web/PojoWebSocketHandler.java	2013-11-16 08:00:52 +0000
603
+++ src/com/goldencode/p2j/web/PojoWebSocketHandler.java	2016-02-20 17:55:05 +0000
604
@@ -10,6 +10,7 @@
605
 **
606
 ** -#- -I- --Date-- ----------------------Description--------------------------
607
 ** 001 MAG 20131105 First version based on jetty 9.1
608
+** 002 SBI 20160220 Added websocket configuration parameters.
609
 */
610
 
611
 package com.goldencode.p2j.web;
612
@@ -23,6 +24,7 @@
613
 import org.eclipse.jetty.websocket.server.*;
614
 import org.eclipse.jetty.websocket.servlet.*;
615
 
616
+
617
 /**
618
  * This class is used to register and handle WebSockets POJO objects. 
619
  * <p>
620
@@ -44,7 +46,10 @@
621
    
622
    /** WebSocketCreator used to create WebSockets by hand */
623
    private WebSocketCreator creator;
624
-
625
+   
626
+   /** Websocket configuration */
627
+   private WebSocketConfig config;
628
+   
629
    /**
630
     * Constructor.
631
     *
632
@@ -55,11 +60,14 @@
633
     * @param   creator
634
     *          The WebSocketCreator instance used tom create 
635
     *          WebSockets by hand.
636
+    * @param   config
637
+    *          The websocket configuration parameters.
638
     */
639
-   public PojoWebSocketHandler(String webSocketTarget, WebSocketCreator creator)
640
+   public PojoWebSocketHandler(String webSocketTarget, WebSocketCreator creator, WebSocketConfig config)
641
    {
642
       this.webSocketTarget = webSocketTarget;
643
       this.creator = creator;
644
+      this.config  = config;
645
    }
646
    
647
    /**
648
@@ -71,11 +79,14 @@
649
     *          of handlers for the same server context.
650
     * @param   webSocketPojo
651
     *          The WebSocket POJO class.
652
+    * @param   config
653
+    *          The websocket configuration parameters.
654
     */
655
-   public PojoWebSocketHandler(String webSocketTarget, Class<?> webSocketPojo)
656
+   public PojoWebSocketHandler(String webSocketTarget, Class<?> webSocketPojo, WebSocketConfig config)
657
    {
658
       this.webSocketTarget = webSocketTarget;
659
       this.webSocketPojo = webSocketPojo;
660
+      this.config = config;
661
    }
662
 
663
    /**
664
@@ -90,6 +101,14 @@
665
    @Override
666
    public void configure(WebSocketServletFactory wsServletFactory)
667
    {
668
+      if (config != null)
669
+      {
670
+         wsServletFactory.getPolicy().setIdleTimeout(config.getMaxIdleTime());
671
+         wsServletFactory.getPolicy().setMaxBinaryMessageSize(config.getMaxBinaryMessage());
672
+         wsServletFactory.getPolicy().setMaxTextMessageBufferSize(config.getMaxTextMessage());
673
+         // used only by streams 
674
+         wsServletFactory.getPolicy().setMaxBinaryMessageBufferSize(config.getMaxBinaryMessage());
675
+      }
676
       if (creator == null)
677
       {
678
          wsServletFactory.register(webSocketPojo);
679

    
680
=== added file 'src/com/goldencode/p2j/web/WebSocketConfig.java'
681
--- src/com/goldencode/p2j/web/WebSocketConfig.java	1970-01-01 00:00:00 +0000
682
+++ src/com/goldencode/p2j/web/WebSocketConfig.java	2016-02-20 18:05:51 +0000
683
@@ -0,0 +1,81 @@
684
+/*
685
+** Module   : WebSocketConfig.java
686
+** Abstract : Wraps Websocket configuration parameters.
687
+**
688
+** Copyright (c) 2016, Golden Code Development Corporation.
689
+** ALL RIGHTS RESERVED. Use is subject to license terms.
690
+**
691
+**         Golden Code Development Corporation
692
+**                 CONFIDENTIAL
693
+**
694
+** -#- -I- --Date-- ------------------------------Description----------------------------------
695
+** 001 SBI 20160220 Added to set the websocket parameters from the server provided configuration.
696
+*/
697
+package com.goldencode.p2j.web;
698
+
699
+import com.goldencode.p2j.cfg.BootstrapConfig;
700
+
701
+/**
702
+ * Wraps Websocket configuration parameters.
703
+ */
704
+public class WebSocketConfig
705
+{
706
+   /**
707
+    * Maximal size of accepted text messages
708
+    */
709
+   private final int maxTextMessage;
710
+   
711
+   /**
712
+    * Maximal idle time
713
+    */
714
+   private final int maxIdleTime;
715
+   
716
+   /**
717
+    * Maximal size of accepted binary messages
718
+    */
719
+   private final int maxBinaryMessage;
720
+
721
+   /**
722
+    * Create an immutable instance of the websocket configuration parameters.
723
+    * 
724
+    * @param    config
725
+    *           The server provided bootstrap configuration.
726
+    */
727
+   public WebSocketConfig(BootstrapConfig config)
728
+   {
729
+      this.maxTextMessage   = config.getInt("client", "web", "maxTextMessage", -1);
730
+      this.maxIdleTime      = config.getInt("client", "web", "maxIdleTime", -1);
731
+      this.maxBinaryMessage = config.getInt("client", "web", "maxBinaryMessage", -1);
732
+   }
733
+
734
+   /**
735
+    * Return the maximal size of accepted text messages.
736
+    * 
737
+    * @return   Maximal size of accepted text messages.
738
+    */
739
+   public int getMaxTextMessage()
740
+   {
741
+      return this.maxTextMessage;
742
+   }
743
+   
744
+   /**
745
+    * Returns the maximal idle time.
746
+    * 
747
+    * @return   Maximal idle time
748
+    */
749
+   public int getMaxIdleTime()
750
+   {
751
+      return this.maxIdleTime;
752
+   }
753
+   
754
+   /**
755
+    * Returns the maximal size of accepted binary messages.
756
+    * 
757
+    * @return   Maximal size of accepted binary messages.
758
+    */
759
+   public int getMaxBinaryMessage()
760
+   {
761
+      return this.maxBinaryMessage;
762
+   }
763
+   
764
+}
765