1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 package nginx.unit.websocket;
18 
19 import java.io.IOException;
20 import java.nio.ByteBuffer;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24 
25 import javax.websocket.SendHandler;
26 import javax.websocket.SendResult;
27 
28 public class WsRemoteEndpointImplClient extends WsRemoteEndpointImplBase {
29 
30     private final AsyncChannelWrapper channel;
31 
WsRemoteEndpointImplClient(AsyncChannelWrapper channel)32     public WsRemoteEndpointImplClient(AsyncChannelWrapper channel) {
33         this.channel = channel;
34     }
35 
36 
37     @Override
isMasked()38     protected boolean isMasked() {
39         return true;
40     }
41 
42 
43     @Override
doWrite(SendHandler handler, long blockingWriteTimeoutExpiry, ByteBuffer... data)44     protected void doWrite(SendHandler handler, long blockingWriteTimeoutExpiry,
45             ByteBuffer... data) {
46         long timeout;
47         for (ByteBuffer byteBuffer : data) {
48             if (blockingWriteTimeoutExpiry == -1) {
49                 timeout = getSendTimeout();
50                 if (timeout < 1) {
51                     timeout = Long.MAX_VALUE;
52                 }
53             } else {
54                 timeout = blockingWriteTimeoutExpiry - System.currentTimeMillis();
55                 if (timeout < 0) {
56                     SendResult sr = new SendResult(new IOException("Blocking write timeout"));
57                     handler.onResult(sr);
58                 }
59             }
60 
61             try {
62                 channel.write(byteBuffer).get(timeout, TimeUnit.MILLISECONDS);
63             } catch (InterruptedException | ExecutionException | TimeoutException e) {
64                 handler.onResult(new SendResult(e));
65                 return;
66             }
67         }
68         handler.onResult(SENDRESULT_OK);
69     }
70 
71     @Override
doClose()72     protected void doClose() {
73         channel.close();
74     }
75 }
76