热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

com.neovisionaries.ws.client.WebSocket类的使用及代码示例

本文整理了Java中com.neovisionaries.ws.client.WebSocket类的一些代码示例,展示了WebSocket类的

本文整理了Java中com.neovisionaries.ws.client.WebSocket类的一些代码示例,展示了WebSocket类的具体用法。这些代码示例主要来源于Github/Stackoverflow/Maven等平台,是从一些精选项目中提取出来的代码,具有较强的参考意义,能在一定程度帮忙到你。WebSocket类的具体详情如下:
包路径:com.neovisionaries.ws.client.WebSocket
类名称:WebSocket

WebSocket介绍

[英]WebSocket.

Create WebSocketFactory

WebSocketFactory is a factory class that creates WebSocket instances. The first step is to create a WebSocketFactory instance.

// Create a WebSocketFactory instance.
WebSocketFactory factory = new
WebSocketFactory#WebSocketFactory();

By default, WebSocketFactory uses javax.net.SocketFactory .javax.net.SocketFactory#getDefault() for non-secure WebSocket connections ( ws:) and javax.net.ssl.SSLSocketFactory.javax.net.ssl.SSLSocketFactory#getDefault() for secure WebSocket connections ( wss:). You can change this default behavior by using WebSocketFactory.WebSocketFactory#setSocketFactory(javax.net.SocketFactory) method, WebSocketFactory.WebSocketFactory#setSSLSocketFactory(javax.net.ssl.SSLSocketFactory) method and WebSocketFactory.WebSocketFactory#setSSLContext(javax.net.ssl.SSLContext) method. Note that you don't have to call a setSSL* method at all if you use the default SSL configuration. Also note that calling setSSLSocketFactory method has no meaning if you have called setSSLContext method. See the description of WebSocketFactory.WebSocketFactory#createSocket(URI) method for details.

The following is an example to set a custom SSL context to a WebSocketFactory instance. (Again, you don't have to call a setSSL* method if you use the default SSL configuration.)

// Create a custom SSL context.
SSLContext cOntext= NaiveSSLContext.getInstance("TLS");
// Set the custom SSL context.
factory.
WebSocketFactory#setSSLContext(javax.net.ssl.SSLContext)(context);
// Disable manual hostname verification for NaiveSSLContext.
//
// Manual hostname verification has been enabled since the
// version 2.1. Because the verification is executed manually
// after Socket.connect(SocketAddress, int) succeeds, the
// hostname verification is always executed even if you has
// passed an SSLContext which naively accepts any server
// certificate. However, this behavior is not desirable in
// some cases and you may want to disable the hostname
// verification. You can disable the hostname verification
// by calling WebSocketFactory.setVerifyHostname(false).
factory.
WebSocketFactory#setVerifyHostname(boolean)(false);

NaiveSSLContext used in the above example is a factory class to create an javax.net.ssl.SSLContext which naively accepts all certificates without verification. It's enough for testing purposes. When you see an error message "unable to find valid certificate path to requested target" while testing, try NaiveSSLContext.

HTTP Proxy

If a WebSocket endpoint needs to be accessed via an HTTP proxy, information about the proxy server has to be set to a WebSocketFactory instance before creating a WebSocketinstance. Proxy settings are represented by ProxySettingsclass. A WebSocketFactory instance has an associated ProxySettings instance and it can be obtained by calling WebSocketFactory.WebSocketFactory#getProxySettings() method.

// Get the associated ProxySettings instance.
ProxySettings settings = factory.
WebSocketFactory#getProxySettings();

ProxySettings class has methods to set information about a proxy server such as ProxySettings#setHost(String)method and ProxySettings#setPort(int) method. The following is an example to set a secure (https) proxy server.

// Set a proxy server.
settings.
ProxySettings#setServer(String)("https://proxy.example.com");

If credentials are required for authentication at a proxy server, ProxySettings#setId(String) method and ProxySettings#setPassword(String) method, or ProxySettings#setCredentials(String,String)method can be used to set the credentials. Note that, however, the current implementation supports only Basic Authentication.

// Set credentials for authentication at a proxy server.
settings.
ProxySettings#setCredentials(String,String)(id, password);

Create WebSocket

WebSocket class represents a WebSocket. Its instances are created by calling one of createSocket methods of a WebSocketFactory instance. Below is the simplest example to create a WebSocket instance.

// Create a WebSocket. The scheme part can be one of the following:
// 'ws', 'wss', 'http' and 'https' (case-insensitive). The user info
// part, if any, is interpreted as expected. If a raw socket failed
// to be created, an IOException is thrown.
WebSocket ws = new
WebSocketFactory#WebSocketFactory().
WebSocketFactory#createSocket(String)("ws://localhost/endpoint");

There are two ways to set a timeout value for socket connection. The first way is to call WebSocketFactory#setConnectionTimeout(int) method of WebSocketFactory.

// Create a WebSocket factory and set 5000 milliseconds as a timeout
// value for socket connection.
WebSocketFactory factory = new WebSocketFactory().
WebSocketFactory#setConnectionTimeout(int)(5000);
// Create a WebSocket. The timeout value set above is used.
WebSocket ws = factory.
WebSocketFactory#createSocket(String)("ws://localhost/endpoint");

The other way is to give a timeout value to a createSocket method.

// Create a WebSocket factory. The timeout value remains 0.
WebSocketFactory factory = new WebSocketFactory();
// Create a WebSocket with a socket connection timeout value.
WebSocket ws = factory.
WebSocketFactory#createSocket(String,int)("ws://localhost/endpoint", 5000);

The timeout value is passed to Socket#connect(java.net.SocketAddress,int) (java.net.SocketAddress , int)method of java.net.Socket.

Register Listener

After creating a WebSocket instance, you should call #addListener(WebSocketListener) method to register a WebSocketListener that receives WebSocket events. WebSocketAdapter is an empty implementation of WebSocketListener interface.

// Register a listener to receive WebSocket events.
ws.
#addListener(WebSocketListener)(new
WebSocketAdapter#WebSocketAdapter() {

@Override
public void
WebSocketListener#onTextMessage(WebSocket,String)(WebSocket websocket, String message) throws Exception {
// Received a text message.
......
}
});

The table below is the list of callback methods defined in WebSocketListenerinterface.

WebSocketListener methodsMethodDescriptionWebSocketListener#handleCallbackError(WebSocket,Throwable)Called when an onXxx() method threw a Throwable.WebSocketListener#onBinaryFrame(WebSocket,WebSocketFrame)Called when a binary frame was received.WebSocketListener#onBinaryMessage(WebSocket,byte[])Called when a binary message was received.WebSocketListener#onCloseFrame(WebSocket,WebSocketFrame)Called when a close frame was received.WebSocketListener#onConnected(WebSocket,Map)Called after the opening handshake succeeded.WebSocketListener#onConnectError(WebSocket,WebSocketException)Called when #connectAsynchronously() failed.WebSocketListener#onContinuationFrame(WebSocket,WebSocketFrame)Called when a continuation frame was received.WebSocketListener#onDisconnected(WebSocket,WebSocketFrame,WebSocketFrame,boolean)Called after a WebSocket connection was closed.WebSocketListener#onError(WebSocket,WebSocketException)Called when an error occurred.WebSocketListener#onFrame(WebSocket,WebSocketFrame)Called when a frame was received.WebSocketListener#onFrameError(WebSocket,WebSocketException,WebSocketFrame)Called when a frame failed to be read.WebSocketListener#onFrameSent(WebSocket,WebSocketFrame)Called when a frame was sent.WebSocketListener#onFrameUnsent(WebSocket,WebSocketFrame)Called when a frame was not sent.WebSocketListener#onMessageDecompressionError(WebSocket,WebSocketException,byte[])Called when a message failed to be decompressed.WebSocketListener#onMessageError(WebSocket,WebSocketException,List)Called when a message failed to be constructed.WebSocketListener#onPingFrame(WebSocket,WebSocketFrame)Called when a ping frame was received.WebSocketListener#onPongFrame(WebSocket,WebSocketFrame)Called when a pong frame was received.WebSocketListener#onSendError(WebSocket,WebSocketException,WebSocketFrame)Called when an error occurred on sending a frame.WebSocketListener#onSendingFrame(WebSocket,WebSocketFrame)Called before a frame is sent.WebSocketListener#onSendingHandshake(WebSocket,String,List)Called before an opening handshake is sent.WebSocketListener#onStateChanged(WebSocket,WebSocketState)Called when the state of WebSocket changed.WebSocketListener#onTextFrame(WebSocket,WebSocketFrame)Called when a text frame was received.WebSocketListener#onTextMessage(WebSocket,String)Called when a text message was received.WebSocketListener#onTextMessageError(WebSocket,WebSocketException,byte[])Called when a text message failed to be constructed.WebSocketListener#onThreadCreated(WebSocket,ThreadType,Thread)Called after a thread was created.WebSocketListener#onThreadStarted(WebSocket,ThreadType,Thread)Called at the beginning of a thread's run() method. WebSocketListener#onThreadStopping(WebSocket,ThreadType,Thread)Called at the end of a thread's run() method. WebSocketListener#onUnexpectedError(WebSocket,WebSocketException)Called when an uncaught throwable was detected.

Configure WebSocket

Before starting a WebSocket opening handshake with the server, you can configure the WebSocket instance by using the following methods.
Methods for ConfigurationMETHODDESCRIPTION#addProtocol(String)Adds an element to Sec-WebSocket-Protocol#addExtension(WebSocketExtension)Adds an element to Sec-WebSocket-Extensions#addHeader(String,String)Adds an arbitrary HTTP header.#setUserInfo(String,String)Adds Authorization header for Basic Authentication.#getSocket()Gets the underlying Socket instance to configure it.#setExtended(boolean)Disables validity checks on RSV1/RSV2/RSV3 and opcode.#setFrameQueueSize(int)Set the size of the frame queue for congestion control.#setMaxPayloadSize(int)Set the maximum payload size.#setMissingCloseFrameAllowed(boolean)Set whether to allow the server to close the connection without sending a close frame.

Connect To Server

By calling #connect() method, connection to the server is established and a WebSocket opening handshake is performed synchronously. If an error occurred during the handshake, a WebSocketException would be thrown. Instead, when the handshake succeeds, the connect() implementation creates threads and starts them to read and write WebSocket frames asynchronously.

try
{
// Connect to the server and perform an opening handshake.
// This method blocks until the opening handshake is finished.
ws.
#connect();
}
catch (
OpeningHandshakeException e)
{
// A violation against the WebSocket protocol was detected
// during the opening handshake.
}
catch (
HostnameUnverifiedException e)
{
// The certificate of the peer does not match the expected hostname.
}
catch (
WebSocketException e)
{
// Failed to establish a WebSocket connection.
}

In some cases, connect() method throws OpeningHandshakeExceptionwhich is a subclass of WebSocketException (since version 1.19). OpeningHandshakeException provides additional methods such as OpeningHandshakeException#getStatusLine(), OpeningHandshakeException#getHeaders() and OpeningHandshakeException#getBody() to access the response from a server. The following snippet is an example to print information that the exception holds.

catch (
OpeningHandshakeException e)
{
// Status line.
StatusLine sl = e.
OpeningHandshakeException#getStatusLine();
System.out.println("=== Status Line ===");
System.out.format("HTTP Version = %s\n", sl.
StatusLine#getHttpVersion());
System.out.format("Status Code = %d\n", sl.
StatusLine#getStatusCode());
System.out.format("Reason Phrase = %s\n", sl.
StatusLine#getReasonPhrase());
// HTTP headers.
Map> headers = e.
OpeningHandshakeException#getHeaders();
System.out.println("=== HTTP Headers ===");
for (Map.Entry> entry : headers.entrySet())
{
// Header name.
String name = entry.getKey();
// Values of the header.
List values = entry.getValue();
if (values == null || values.size() == 0)
{
// Print the name only.
System.out.println(name);
continue;
}
for (String value : values)
{
// Print the name and the value.
System.out.format("%s: %s\n", name, value);
}
}
}

Also, connect() method throws HostnameUnverifiedExceptionwhich is a subclass of WebSocketException (since version 2.1) when the certificate of the peer does not match the expected hostname.

Connect To Server Asynchronously

The simplest way to call connect() method asynchronously is to use #connectAsynchronously() method. The implementation of the method creates a thread and calls connect() method in the thread. When the connect() call failed, WebSocketListener#onConnectError(WebSocket,WebSocketException) of WebSocketListener would be called. Note that onConnectError() is called only when connectAsynchronously()was used and the connect() call executed in the background thread failed. Neither direct synchronous connect() nor WebSocket#connect(java.util.concurrent.ExecutorService) (described below) will trigger the callback method.

// Connect to the server asynchronously.
ws.
#connectAsynchronously();

Another way to call connect() method asynchronously is to use #connect(ExecutorService) method. The method performs a WebSocket opening handshake asynchronously using the given ExecutorService.

// Prepare an ExecutorService.
ExecutorService es =
java.util.concurrent.Executors.
java.util.concurrent.Executors#newSingleThreadExecutor();
// Connect to the server asynchronously.
Future future = ws.
#connect(ExecutorService)(es);
try
{
// Wait for the opening handshake to complete.
future.get();
}
catch (
java.util.concurrent.ExecutionException e)
{
if (e.getCause() instanceof
WebSocketException)
{
......
}
}

The implementation of connect(ExecutorService) method creates a java.util.concurrent.Callable instance by calling #connectable() method and passes the instance to ExecutorService#submit(Callable)method of the given ExecutorService. What the implementation of Callable#call() method of the Callableinstance does is just to call the synchronous connect().

Send Frames

WebSocket frames can be sent by #sendFrame(WebSocketFrame)method. Other sendXxx methods such as #sendText(String) are aliases of sendFrame method. All of the sendXxx methods work asynchronously. However, under some conditions, sendXxx methods may block. See Congestion Control for details.

Below are some examples of sendXxx methods. Note that in normal cases, you don't have to call #sendClose() method and #sendPong() (or their variants) explicitly because they are called automatically when appropriate.

// Send a text frame.
ws.
#sendText(String)("Hello.");
// Send a binary frame.
byte[] binary = ......;
ws.
#sendBinary(byte[])(binary);
// Send a ping frame.
ws.
#sendPing(String)("Are you there?");

If you want to send fragmented frames, you have to know the details of the specification (5.4. Fragmentation). Below is an example to send a text message ( "How are you?") which consists of 3 fragmented frames.

// The first frame must be either a text frame or a binary frame.
// And its FIN bit must be cleared.
WebSocketFrame firstFrame = WebSocketFrame
.
WebSocketFrame#createTextFrame(String)("How ")
.
WebSocketFrame#setFin(boolean)(false);
// Subsequent frames must be continuation frames. The FIN bit of
// all continuation frames except the last one must be cleared.
// Note that the FIN bit of frames returned from
// WebSocketFrame.createContinuationFrame methods is cleared, so
// the example below does not clear the FIN bit explicitly.
WebSocketFrame secOndFrame= WebSocketFrame
.
WebSocketFrame#createContinuationFrame(String)("are ");
// The last frame must be a continuation frame with the FIN bit set.
// Note that the FIN bit of frames returned from
// WebSocketFrame.createContinuationFrame methods is cleared, so
// the FIN bit of the last frame must be set explicitly.
WebSocketFrame lastFrame = WebSocketFrame
.
WebSocketFrame#createContinuationFrame(String)("you?")
.
WebSocketFrame#setFin(boolean)(true);
// Send a text message which consists of 3 frames.
ws.
#sendFrame(WebSocketFrame)(firstFrame)
.
#sendFrame(WebSocketFrame)(secondFrame)
.
#sendFrame(WebSocketFrame)(lastFrame);

Alternatively, the same as above can be done like this.

// Send a text message which consists of 3 frames.
ws.
#sendText(String,boolean)("How ", false)
.
#sendContinuation(String)("are ")
.
#sendContinuation(String,boolean)("you?", true);

Send Ping/Pong Frames Periodically

You can send ping frames periodically by calling #setPingInterval(long) method with an interval in milliseconds between ping frames. This method can be called both before and after #connect() method. Passing zero stops the periodical sending.

// Send a ping per 60 seconds.
ws.
#setPingInterval(long)(60 * 1000);
// Stop the periodical sending.
ws.
#setPingInterval(long)(0);

Likewise, you can send pong frames periodically by calling #setPongInterval(long) method. "A Pong frame MAY be sent unsolicited." (RFC 6455, 5.5.3. Pong)

You can customize payload of ping/pong frames that are sent automatically by using #setPingPayloadGenerator(PayloadGenerator) and #setPongPayloadGenerator(PayloadGenerator) methods. Both methods take an instance of PayloadGenerator interface. The following is an example to use the string representation of the current date as payload of ping frames.

ws.
#setPingPayloadGenerator(PayloadGenerator)(new
PayloadGenerator () {

@Override
public byte[] generate() {
// The string representation of the current date.
return new Date().toString().getBytes();
}
});

Note that the maximum payload length of control frames (e.g. ping frames) is 125. Therefore, the length of a byte array returned from PayloadGenerator#generate() method must not exceed 125.

You can change the names of the java.util.Timers that send ping/pong frames periodically by using #setPingSenderName(String) and #setPongSenderName(String) methods.

// Change the Timers' names.
ws.
#setPingSenderName(String)("PING_SENDER");
ws.
#setPongSenderName(String)("PONG_SENDER");

Auto Flush

By default, a frame is automatically flushed to the server immediately after #sendFrame(WebSocketFrame) method is executed. This automatic flush can be disabled by calling #setAutoFlush(boolean)(false).

// Disable auto-flush.
ws.
#setAutoFlush(boolean)(false);

To flush frames manually, call #flush() method. Note that this method works asynchronously.

// Flush frames to the server manually.
ws.
#flush();

Congestion Control

sendXxx methods queue a WebSocketFrame instance to the internal queue. By default, no upper limit is imposed on the queue size, so sendXxx methods do not block. However, this behavior may cause a problem if your WebSocket client application sends too many WebSocket frames in a short time for the WebSocket server to process. In such a case, you may want sendXxx methods to block when many frames are queued.

You can set an upper limit on the internal queue by calling #setFrameQueueSize(int)method. As a result, if the number of frames in the queue has reached the upper limit when a sendXxx method is called, the method blocks until the queue gets spaces. The code snippet below is an example to set 5 as the upper limit of the internal frame queue.

// Set 5 as the frame queue size.
ws.
#setFrameQueueSize(int)(5);

Note that under some conditions, even if the queue is full, sendXxx methods do not block. For example, in the case where the thread to send frames ( WritingThread) is going to stop or has already stopped. In addition, method calls to send a control frame (e.g. #sendClose() and #sendPing()) do not block.

Maximum Payload Size

You can set an upper limit on the payload size of WebSocket frames by calling #setMaxPayloadSize(int) method with a positive value. Text, binary and continuation frames whose payload size is bigger than the maximum payload size you have set will be split into multiple frames.

// Set 1024 as the maximum payload size.
ws.
#setMaxPayloadSize(int)(1024);

Control frames (close, ping and pong frames) are never split as per the specification.

If permessage-deflate extension is enabled and if the payload size of a WebSocket frame after compression does not exceed the maximum payload size, the WebSocket frame is not split even if the payload size before compression execeeds the maximum payload size.

Compression

The permessage-deflate extension (RFC 7692) has been supported since the version 1.17. To enable the extension, call #addExtension(String) method with "permessage-deflate".

// Enable "permessage-deflate" extension (RFC 7692).
ws.
#addExtension(String)(
WebSocketExtension#PERMESSAGE_DEFLATE);

Missing Close Frame

Some server implementations close a WebSocket connection without sending a close frame to a client in some cases. Strictly speaking, this is a violation against the specification (RFC 6455). However, this library has allowed the behavior by default since the version 1.29. Even if the end of the input stream of a WebSocket connection were reached without a close frame being received, it would trigger neither WebSocketListener#onError(WebSocket,WebSocketException) method nor WebSocketListener#onFrameError(WebSocket,WebSocketException,WebSocketFrame) method of WebSocketListener. If you want to make a WebSocket instance report an error in the case, pass false to #setMissingCloseFrameAllowed(boolean) method.

// Make this library report an error when the end of the input stream
// of the WebSocket connection is reached before a close frame is read.
ws.
#setMissingCloseFrameAllowed(boolean)(false);

Direct Text Message

When a text message was received, WebSocketListener#onTextMessage(WebSocket,String) is called. The implementation internally converts the byte array of the text message into a String object before calling the listener method. If you want to receive the byte array directly without the string conversion, call #setDirectTextMessage(boolean) with true, and WebSocketListener#onTextMessage(WebSocket,byte[])will be called instead.

// Receive text messages without string conversion.
ws.
#setDirectTextMessage(boolean)(true);

Disconnect WebSocket

Before a WebSocket is closed, a closing handshake is performed. A closing handshake is started (1) when the server sends a close frame to the client or (2) when the client sends a close frame to the server. You can start a closing handshake by calling #disconnect() method (or by sending a close frame manually).

// Close the WebSocket connection.
ws.
#disconnect();

disconnect() method has some variants. If you want to change the close code and the reason phrase of the close frame that this client will send to the server, use a variant method such as #disconnect(int,String). disconnect()method itself is an alias of disconnect(WebSocketCloseCode.NORMAL, null).

Reconnection

connect() method can be called at most only once regardless of whether the method succeeded or failed. If you want to re-connect to the WebSocket endpoint, you have to create a new WebSocket instance again by calling one of createSocket methods of a WebSocketFactory. You may find #recreate()method useful if you want to create a new WebSocket instance that has the same settings as the original instance. Note that, however, settings you made on the raw socket of the original WebSocket instance are not copied.

// Create a new WebSocket instance and connect to the same endpoint.
ws = ws.
#recreate().
#connect();

There is a variant of recreate() method that takes a timeout value for socket connection. If you want to use a timeout value that is different from the one used when the existing WebSocket instance was created, use #recreate(int) method.

Note that you should not trigger reconnection in WebSocketListener#onError(WebSocket,WebSocketException) method because onError() may be called multiple times due to one error. Instead, WebSocketListener#onDisconnected(WebSocket,WebSocketFrame,WebSocketFrame,boolean) is the right place to trigger reconnection.

Also note that the reason I use an expression of "to trigger reconnection" instead of "to call recreate().connect()" is that I myself won't do it synchronously in WebSocketListener callback methods but will just schedule reconnection or will just go to the top of a kind of application loop that repeats to establish a WebSocket connection until it succeeds.

Error Handling

WebSocketListener has some onXxxError() methods such as WebSocketListener#onFrameError(WebSocket,WebSocketException,WebSocketFrame) and WebSocketListener#onSendError(WebSocket,WebSocketException,WebSocketFrame). Among such methods, WebSocketListener#onError(WebSocket,WebSocketException) is a special one. It is always called before any other onXxxError() is called. For example, in the implementation of run() method of ReadingThread, Throwable is caught and onError() and WebSocketListener#onUnexpectedError(WebSocket,WebSocketException) are called in this order. The following is the implementation.

@Override
public void run()
{
try
{
main();
}
catch (Throwable t)
{
// An uncaught throwable was detected in the reading thread.
WebSocketException cause = new WebSocketException(
WebSocketError.
WebSocketError#UNEXPECTED_ERROR_IN_READING_THREAD,
"An uncaught throwable was detected in the reading thread", t);
// Notify the listeners.
ListenerManager manager = mWebSocket.getListenerManager();
manager.callOnError(cause);
manager.callOnUnexpectedError(cause);
}
}

So, you can handle all error cases in onError() method. However, note that onError() may be called multiple times for one error cause, so don't try to trigger reconnection in onError(). Instead, WebSocketListener#onDisconnected(WebSocket,WebSocketFrame,WebSocketFrame,boolean) is the right place to trigger reconnection.

All onXxxError() methods receive a WebSocketException instance as the second argument (the first argument is a WebSocket instance). The exception class provides WebSocketException#getError() method which returns a WebSocketError enum entry. Entries in WebSocketErrorenum are possible causes of errors that may occur in the implementation of this library. The error causes are so granular that they can make it easy for you to find the root cause when an error occurs.

Throwables thrown by implementations of onXXX() callback methods are passed to WebSocketListener#handleCallbackError(WebSocket,Throwable) of WebSocketListener.

@Override
public void
WebSocketListener#handleCallbackError(WebSocket,Throwable)(WebSocket websocket, Throwable cause) throws Exception {
// Throwables thrown by onXxx() callback methods come here.
}

Thread Callbacks

Some threads are created internally in the implementation of WebSocket. Known threads are as follows.
Internal ThreadsTHREAD TYPEDESCRIPTIONThreadType#READING_THREADA thread which reads WebSocket frames from the server.ThreadType#WRITING_THREADA thread which sends WebSocket frames to the server.ThreadType#CONNECT_THREADA thread which calls WebSocket#connect() asynchronously.ThreadType#FINISH_THREADA thread which does finalization of a WebSocket instance.

The following callback methods of WebSocketListener are called according to the life cycle of the threads.

Thread CallbacksMETHODDESCRIPTIONWebSocketListener#onThreadCreated(WebSocket,ThreadType,Thread)Called after a thread was created.WebSocketListener#onThreadStarted(WebSocket,ThreadType,Thread)Called at the beginning of the thread's run() method.WebSocketListener#onThreadStopping(WebSocket,ThreadType,Thread)Called at the end of the thread's run() method.

For example, if you want to change the name of the reading thread, implement WebSocketListener#onThreadCreated(WebSocket,ThreadType,Thread) method like below.

@Override
public void
WebSocketListener#onThreadCreated(WebSocket,ThreadType,Thread)(WebSocket websocket,
ThreadType type, Thread thread)
{
if (type == ThreadType.READING_THREAD)
{
thread.setName("READING_THREAD");
}
}

[中]WebSocket。
####创建WebSocketFactory
WebSocketFactory是一个创建WebSocket实例的工厂类。第一步是创建WebSocketFactory实例。

// Create a WebSocketFactory instance.
WebSocketFactory factory = new
WebSocketFactory#WebSocketFactory();

默认情况下,WebSocketFactory使用javax。网袜子工厂。javax。网SocketFactory#getDefault()用于非安全WebSocket连接(ws:)和javax。网ssl。SSLSocketFactory。javax。网ssl。用于安全WebSocket连接(wss:)的SSLSocketFactory#getDefault()。可以使用WebSocketFactory更改此默认行为。WebSocketFactory#setSocketFactory(javax.net.SocketFactory)方法,WebSocketFactory。WebSocketFactory#setSSLSocketFactory(javax.net.ssl.SSLSocketFactory)方法和WebSocketFactory。WebSocketFactory#setSSLContext(javax.net.ssl.SSLContext)方法。请注意,如果使用默认SSL配置,则根本不必调用setSSL方法。还请注意,如果调用了setSSLContext方法,那么调用setSSLSocketFactory方法没有任何意义。请参阅WebSocketFactory的说明。WebSocketFactory#createSocket(URI)方法获取详细信息。
下面是一个为WebSocketFactory实例设置自定义SSL上下文的示例。(同样,如果使用默认SSL配置,则不必调用setSSL
方法。)

// Create a custom SSL context.
SSLContext cOntext= NaiveSSLContext.getInstance("TLS");
// Set the custom SSL context.
factory.
WebSocketFactory#setSSLContext(javax.net.ssl.SSLContext)(context);
// Disable manual hostname verification for NaiveSSLContext.
//
// Manual hostname verification has been enabled since the
// version 2.1. Because the verification is executed manually
// after Socket.connect(SocketAddress, int) succeeds, the
// hostname verification is always executed even if you has
// passed an SSLContext which naively accepts any server
// certificate. However, this behavior is not desirable in
// some cases and you may want to disable the hostname
// verification. You can disable the hostname verification
// by calling WebSocketFactory.setVerifyHostname(false).
factory.
WebSocketFactory#setVerifyHostname(boolean)(false);

上面示例中使用的{$1$}是一个用于创建javax的工厂类。网ssl。SSLContext,它在未经验证的情况下天真地接受所有证书。这对于测试来说已经足够了。当您在测试时看到错误消息“无法找到请求目标的有效证书路径”时,请尝试NaiveSSLContext。
####HTTP代理
如果需要通过HTTP代理访问WebSocket端点,则在创建WebSocketinstance之前,必须将有关代理服务器的信息设置为WebSocketFactory实例。代理设置由ProxySettingsclass表示。WebSocketFactory实例具有关联的ProxySettings实例,可以通过调用WebSocketFactory来获取该实例。WebSocketFactory#getProxySettings()方法。

// Get the associated ProxySettings instance.
ProxySettings settings = factory.
WebSocketFactory#getProxySettings();

ProxySettings类具有设置代理服务器信息的方法,例如ProxySettings#setHost(字符串)方法和ProxySettings#setPort(int)方法。以下是设置安全(https)代理服务器的示例。

// Set a proxy server.
settings.
ProxySettings#setServer(String)("https://proxy.example.com");

如果代理服务器上的身份验证需要凭据,则可以使用ProxySettings#setId(String)方法和ProxySettings#setPassword(String)方法或ProxySettings#setCredentials(String,String)方法设置凭据。但是,请注意,当前的实现只支持基本身份验证。

// Set credentials for authentication at a proxy server.
settings.
ProxySettings#setCredentials(String,String)(id, password);

####创建WebSocket
WebSocket类表示一个WebSocket。其实例是通过调用WebSocketFactory实例的createSocket方法之一创建的。下面是创建WebSocket实例的最简单示例。

// Create a WebSocket. The scheme part can be one of the following:
// 'ws', 'wss', 'http' and 'https' (case-insensitive). The user info
// part, if any, is interpreted as expected. If a raw socket failed
// to be created, an IOException is thrown.
WebSocket ws = new
WebSocketFactory#WebSocketFactory().
WebSocketFactory#createSocket(String)("ws://localhost/endpoint");

有两种方法可以设置套接字连接的超时值。第一种方法是调用WebSocketFactory的#setConnectionTimeout(int)方法。

// Create a WebSocket factory and set 5000 milliseconds as a timeout
// value for socket connection.
WebSocketFactory factory = new WebSocketFactory().
WebSocketFactory#setConnectionTimeout(int)(5000);
// Create a WebSocket. The timeout value set above is used.
WebSocket ws = factory.
WebSocketFactory#createSocket(String)("ws://localhost/endpoint");

另一种方法是为createSocket方法提供一个超时值。

// Create a WebSocket factory. The timeout value remains 0.
WebSocketFactory factory = new WebSocketFactory();
// Create a WebSocket with a socket connection timeout value.
WebSocket ws = factory.
WebSocketFactory#createSocket(String,int)("ws://localhost/endpoint", 5000);

超时值被传递给java的Socket#connect(java.net.SocketAddress,int)(java.net.SocketAddress,int)方法。网插座
####注册侦听器
创建WebSocket实例后,应该调用#addListener(WebSocketListener)方法来注册接收WebSocket事件的WebSocketListener。WebSocketAdapter是WebSocketListener接口的空实现。

// Register a listener to receive WebSocket events.
ws.
#addListener(WebSocketListener)(new
WebSocketAdapter#WebSocketAdapter() {

@Override
public void
WebSocketListener#onTextMessage(WebSocket,String)(WebSocket websocket, String message) throws Exception {
// Received a text message.
......
}
});

下表列出了WebSocketListenerinterface中定义的回调方法。
WebSocketListener methodsMethodDescriptionWebSocketListener#handleCallbackError(WebSocket,Throwable)在onXxx()方法抛出Throwable时调用。WebSocketListener#onBinaryFrame(WebSocket,WebSocketFrame)在收到二进制帧时调用。WebSocketListener#onBinaryMessage(WebSocket,字节[])在收到二进制消息时调用。WebSocketListener#onCloseFrame(WebSocket,WebSocketFrame)在接收到关闭帧时调用。WebSocketListener#OnConnect(WebSocket,Map)在开场握手成功后调用。当#connectAsynchronously()失败时调用WebSocketListener#onConnectError(WebSocket,WebSocketException)。WebSocketListener#onContinuationFrame(WebSocket,WebSocketFrame)在接收到延续帧时调用。WebSocketListener#onDisconnected(WebSocket、WebSocketFrame、WebSocketFrame、boolean)在WebSocket连接关闭后调用。WebSocketListener#OneError(WebSocket,WebSocketException)在发生错误时调用。WebSocketListener#onFrame(WebSocket,WebSocketFrame)在收到帧时调用。无法读取帧时调用WebSocketListener#onFrameError(WebSocket、WebSocketException、WebSocketFrame)。WebSocketListener#onFrameSent(WebSocket,WebSocketFrame)在发送帧时调用。未发送帧时调用WebSocketListener#onFrameUnsent(WebSocket,WebSocketFrame)。WebSocketListener#onMessageDecompressionError(WebSocket,WebSocketException,字节[])在消息解压缩失败时调用。当消息构造失败时调用WebSocketListener#onMessageError(WebSocket,WebSocketException,List)。WebSocketListener#onPingFrame(WebSocket,WebSocketFrame)在收到ping帧时调用。WebSocketListener#onPongFrame(WebSocket,WebSocketFrame)在收到pong帧时调用。在发送帧时出错时调用WebSocketListener#OnSenderError(WebSocket、WebSocketException、WebSocketFrame)。在发送帧之前调用WebSocketListener#onSendingFrame(WebSocket,WebSocketFrame)。WebSocketListener#onSendingHandshake(WebSocket、字符串、列表)在发送开始握手之前调用。WebSocketListener#onStateChanged(WebSocket,WebSocketState)在WebSocket的状态更改时调用。WebSocketListener#onTextFrame(WebSocket,WebSocketFrame)在收到文本帧时调用。WebSocketListener#在收到文本消息时调用ContextMessage(WebSocket,String)。无法构造文本消息时调用WebSocketListener#onTextMessageError(WebSocket,WebSocketException,字节[])。WebSocketListener#onThreadCreated(WebSocket、ThreadType、Thread)在创建线程后调用。WebSocketListener#onThreadStarted(WebSocket、ThreadType、Thread)在线程的run()方法开始时调用。WebSocketListener#onThreadStopping(WebSocket、ThreadType、Thread)在线程的run()方法末尾调用。WebSocketListener#onNext PropectedError(WebSocket,WebSocketException)在检测到未捕获的可丢弃内容时调用。
####配置WebSocket
在使用服务器启动WebSocketopening handshake之前,可以使用以下方法配置WebSocket实例。
ConfigurationMETHODDESCRIPTION方法#addProtocol(String)向Sec WebSocket协议添加元素#addExtension(WebSocketExtension)向Sec WebSocket Extensions添加元素#addHeader(String,String)添加任意HTTP头#setUserInfo(String,String)为基本身份验证添加授权头#getSocket()获取底层套接字实例以对其进行配置#setExtended(布尔)禁用RSV1/RSV2/RSV3和操作码的有效性检查#setFrameQueueSize(int)为congestion control设置帧队列的大小#setMaxPayloadSize(int)设置maximum payload size#setMissingCloseFrameAllowed(布尔值)设置是否允许服务器关闭连接而不发送关闭帧。
####连接到服务器
通过调用#connect()方法,建立与服务器的连接,并同步执行WebSocket打开握手。如果握手过程中发生错误,将抛出WebSocketException。相反,当握手成功时,connect()实现会创建线程,并启动它们异步读写WebSocket帧。

try
{
// Connect to the server and perform an opening handshake.
// This method blocks until the opening handshake is finished.
ws.
#connect();
}
catch (
OpeningHandshakeException e)
{
// A violation against the WebSocket protocol was detected
// during the opening handshake.
}
catch (
HostnameUnverifiedException e)
{
// The certificate of the peer does not match the expected hostname.
}
catch (
WebSocketException e)
{
// Failed to establish a WebSocket connection.
}

在某些情况下,connect()方法会抛出OpeningHandShakeException,这是WebSocketException(自版本1.19起)的子类。OpeningHandshakeException提供了其他方法,如OpeningHandshakeException#getStatusLine()、OpeningHandshakeException#getHeaders()和OpeningHandshakeException#getBody()来访问服务器的响应。下面的代码片段是打印异常保存的信息的示例。

catch (
OpeningHandshakeException e)
{
// Status line.
StatusLine sl = e.
OpeningHandshakeException#getStatusLine();
System.out.println("=== Status Line ===");
System.out.format("HTTP Version = %s\n", sl.
StatusLine#getHttpVersion());
System.out.format("Status Code = %d\n", sl.
StatusLine#getStatusCode());
System.out.format("Reason Phrase = %s\n", sl.
StatusLine#getReasonPhrase());
// HTTP headers.
Map> headers = e.
OpeningHandshakeException#getHeaders();
System.out.println("=== HTTP Headers ===");
for (Map.Entry> entry : headers.entrySet())
{
// Header name.
String name = entry.getKey();
// Values of the header.
List values = entry.getValue();
if (values == null || values.size() == 0)
{
// Print the name only.
System.out.println(name);
continue;
}
for (String value : values)
{
// Print the name and the value.
System.out.format("%s: %s\n", name, value);
}
}
}

此外,connect()方法在对等方的证书与预期主机名不匹配时抛出hostnameUnverifiedException,它是WebSocketException(自版本2.1起)的子类。
####异步连接到服务器
异步调用connect()方法的最简单方法是使用#connectAsynchronously()方法。该方法的实现将创建一个线程,并在该线程中调用connect()方法。当connect()调用失败时,将调用WebSocketListener的WebSocketListener#onConnectError(WebSocket,WebSocketException)。请注意,只有在使用connectAsynchronously()且在后台线程中执行的connect()调用失败时,才会调用onConnectError()。direct synchronous connect()和WebSocket#connect(java.util.concurrent.ExecutorService)(如下所述)都不会触发回调方法。

// Connect to the server asynchronously.
ws.
#connectAsynchronously();

异步调用connect()方法的另一种方法是使用#connect(ExecutorService)方法。该方法使用给定的ExecutorService异步执行WebSocket打开握手。

// Prepare an ExecutorService.
ExecutorService es =
java.util.concurrent.Executors.
java.util.concurrent.Executors#newSingleThreadExecutor();
// Connect to the server asynchronously.
Future future = ws.
#connect(ExecutorService)(es);
try
{
// Wait for the opening handshake to complete.
future.get();
}
catch (
java.util.concurrent.ExecutionException e)
{
if (e.getCause() instanceof
WebSocketException)
{
......
}
}

connect(ExecutorService)方法的实现创建了一个java。util。同时发生的通过调用#connectable()方法调用可调用实例,并将实例传递给给定ExecutorService的#submit(可调用)方法。Callableinstance的Callable#call()方法的实现只是调用同步connect()。
####发送帧
WebSocket帧可以通过#sendFrame(WebSocketFrame)方法发送。其他sendXxx方法,如#sendText(String)是sendFrame方法的别名。所有sendXxx方法都是异步工作的。但是,在某些情况下,sendXxx方法可能会阻塞。有关详细信息,请参见Congestion Control。
下面是一些sendXxx方法的示例。请注意,在正常情况下,您不必显式调用#sendClose()方法和#sendPong()(或其变体),因为它们会在适当时自动调用。

// Send a text frame.
ws.
#sendText(String)("Hello.");
// Send a binary frame.
byte[] binary = ......;
ws.
#sendBinary(byte[])(binary);
// Send a ping frame.
ws.
#sendPing(String)("Are you there?");

如果你想发送碎片帧,你必须知道规范的细节(5.4. Fragmentation)。下面是一个发送短信的示例(“你好吗?”)它由3个支离破碎的帧组成。

// The first frame must be either a text frame or a binary frame.
// And its FIN bit must be cleared.
WebSocketFrame firstFrame = WebSocketFrame
.
WebSocketFrame#createTextFrame(String)("How ")
.
WebSocketFrame#setFin(boolean)(false);
// Subsequent frames must be continuation frames. The FIN bit of
// all continuation frames except the last one must be cleared.
// Note that the FIN bit of frames returned from
// WebSocketFrame.createContinuationFrame methods is cleared, so
// the example below does not clear the FIN bit explicitly.
WebSocketFrame secOndFrame= WebSocketFrame
.
WebSocketFrame#createContinuationFrame(String)("are ");
// The last frame must be a continuation frame with the FIN bit set.
// Note that the FIN bit of frames returned from
// WebSocketFrame.createContinuationFrame methods is cleared, so
// the FIN bit of the last frame must be set explicitly.
WebSocketFrame lastFrame = WebSocketFrame
.
WebSocketFrame#createContinuationFrame(String)("you?")
.
WebSocketFrame#setFin(boolean)(true);
// Send a text message which consists of 3 frames.
ws.
#sendFrame(WebSocketFrame)(firstFrame)
.
#sendFrame(WebSocketFrame)(secondFrame)
.
#sendFrame(WebSocketFrame)(lastFrame);

或者,与

代码示例

代码示例来源:origin: TakahikoKawasaki/nv-websocket-client

@Override
public WebSocket call() throws WebSocketException
{
return mWebSocket.connect();
}
}

代码示例来源:origin: DV8FromTheWorld/JDA

protected void send(String message)
{
LOG.trace("<- {}", message);
socket.sendText(message);
}

代码示例来源:origin: TakahikoKawasaki/nv-websocket-client

/**
* Disconnect the WebSocket.
*
*


* This method is an alias of {@link #disconnect(int, String)
* disconnect}{@code (}{@link WebSocketCloseCode#NORMAL}{@code , null)}.
*


*
* @return
* {@code this} object.
*/
public WebSocket disconnect()
{
return disconnect(WebSocketCloseCode.NORMAL, null);
}

代码示例来源:origin: TakahikoKawasaki/nv-websocket-client

private void doTask()
{
synchronized (this)
{
if (mInterval == 0 || mWebSocket.isOpen() == false)
{
mScheduled = false;
// Not schedule a new task.
return;
}
// Create a frame and send it to the server.
mWebSocket.sendFrame(createFrame());
// Schedule a new task.
mScheduled = schedule(mTimer, new Task(), mInterval);
}
}

代码示例来源:origin: DV8FromTheWorld/JDA

protected synchronized void connect()
{
if (api.getStatus() != JDA.Status.ATTEMPTING_TO_RECONNECT)
api.setStatus(JDA.Status.CONNECTING_TO_WEBSOCKET);
if (shutdown)
throw new RejectedExecutionException("JDA is shutdown!");
initiating = true;
String url = api.getGatewayUrl() + "?encoding=json&v=" + DISCORD_GATEWAY_VERSION;
if (compression)
{
url += "&compress=zlib-stream";
decompressBuffer = newDecompressBuffer();
}
try
{
socket = api.getWebSocketFactory()
.createSocket(url)
.addHeader("Accept-Encoding", "gzip")
.addListener(this);
socket.connect();
}
catch (IOException | WebSocketException e)
{
api.resetGatewayUrl();
//Completely fail here. We couldn't make the connection.
throw new IllegalStateException(e);
}
}

代码示例来源:origin: blockchain/Android-Merchant-App

.addHeader("Origin", "https://blockchain.info").recreate()
.addListener(new WebSocketAdapter() {
mConnection.connect();

代码示例来源:origin: io.github.sac/SocketclusterClientJava

e.printStackTrace();
ws.addExtension("permessage-deflate; client_max_window_bits");
for (Map.Entry entry : headers.entrySet()) {
ws.addHeader(entry.getKey(), entry.getValue());
ws.addListener(adapter);
ws.connect();
} catch (OpeningHandshakeException e) {

代码示例来源:origin: FlareBot/FlareBot

@Override
public WebSocket createSocket(URI uri) throws IOException {
WebSocket socket = super.createSocket(uri);
socket.addListener(this.listener);
return socket;
}

代码示例来源:origin: io.github.sac/SocketclusterClientJava

public void connectAsync() {
try {
ws = factory.createSocket(URL);
} catch (IOException e) {
e.printStackTrace();
}
ws.addExtension("permessage-deflate; client_max_window_bits");
for (Map.Entry entry : headers.entrySet()) {
ws.addHeader(entry.getKey(), entry.getValue());
}
ws.addListener(adapter);
ws.connectAsynchronously();
}

代码示例来源:origin: stackoverflow.com

wsf.setSSLContext(context);
ws = wsf.createSocket("wss://" + ADDRESS);
ws.addListener(new WSListener());
ws.addExtension(WebSocketExtension.parse(WebSocketExtension.PERMESSAGE_DEFLATE));
ws.connect();
} catch (Exception e) {
e.printStackTrace();

代码示例来源:origin: net.dv8tion/JDA

.addListener(this)
.connect();

代码示例来源:origin: DV8FromTheWorld/JDA

protected void startConnection()
{
if (!reconnecting && socket != null)
throw new IllegalStateException("Somehow, someway, this AudioWebSocket has already attempted to start a connection!");
try
{
socket = getJDA().getWebSocketFactory()
.createSocket(wssEndpoint)
.addListener(this);
changeStatus(ConnectionStatus.CONNECTING_AWAITING_WEBSOCKET_CONNECT);
socket.connectAsynchronously();
}
catch (IOException e)
{
LOG.warn("Encountered IOException while attempting to connect: {}\nClosing connection and attempting to reconnect.", e.getMessage());
this.close(ConnectionStatus.ERROR_WEBSOCKET_UNABLE_TO_CONNECT);
}
}

代码示例来源:origin: twitch4j/twitch4j

this.webSocket.clearListeners();
this.webSocket.addListener(new WebSocketAdapter() {

代码示例来源:origin: delight-im/Android-DDP

/**
* Opens a connection to the server over websocket
*
* @param isReconnect whether this is a re-connect attempt or not
*/
private void openConnection(final boolean isReconnect) {
if (isReconnect) {
if (mConnected) {
initConnection(mSessionID);
return;
}
}
// create a new WebSocket connection for the data transfer
try {
mWebSocket = new WebSocketFactory().setConnectionTimeout(30000).createSocket(mServerUri);
}
catch (final IOException e) {
mCallbackProxy.onException(e);
}
mWebSocket.setMissingCloseFrameAllowed(true);
mWebSocket.setPingInterval(25 * 1000);
mWebSocket.addListener(mWebSocketListener);
mWebSocket.connectAsynchronously();
}

代码示例来源:origin: Javacord/Javacord

websocket.removeListeners(identifyFrameListeners);
identifyFrameListeners.clear();
websocket.addListener(identifyFrameListener);
logger.debug("Sending identify packet");
websocket.sendFrame(identifyFrame);

代码示例来源:origin: blockchain/Android-Merchant-App

private void send(String message) {
//Make sure each message is only sent once per socket lifetime
if(!sentMessageSet.contains(message)) {
try {
if (mConnection != null && mConnection.isOpen()) {
mConnection.sendText(message);
sentMessageSet.add(message);
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
// Log.d("WebSocketHandler", "Message sent already: "+message);
}
}

代码示例来源:origin: twitch4j/twitch4j

/**
* Disconnecting from WebSocket
*/
@Synchronized
public void disconnect() {
if (connectionState.equals(TMIConnectionState.CONNECTED)) {
cOnnectionState= TMIConnectionState.DISCONNECTING;
}
cOnnectionState= TMIConnectionState.DISCONNECTED;
// CleanUp
this.webSocket.clearListeners();
this.webSocket.disconnect();
this.webSocket = null;
}

代码示例来源:origin: blockchain/Android-Merchant-App

public void stop() {
stopPingTimer();
if(mConnection != null && mConnection.isOpen()) {
mConnection.disconnect();
}
}

代码示例来源:origin: TakahikoKawasaki/nv-websocket-client

if (mWebSocket.isOpen() == false)

代码示例来源:origin: DV8FromTheWorld/JDA

public void close()
{
if (socket != null)
socket.sendClose(1000);
}

推荐阅读
  • 在Python中,是否可以通过使用Tkinter或ttk库创建一个具有自动换行功能的多行标签,并使其宽度能够随着父容器的变化而动态调整?例如,在调整NotePad窗口宽度时,实现类似记事本的自动换行效果。这种功能在设计需要显示长文本的对话框时非常有用,确保文本内容能够完整且美观地展示。 ... [详细]
  • SSL 错误:目标主机名与备用证书主题名称不匹配
    在使用 `git clone` 命令时,常见的 SSL 错误表现为:无法访问指定的 HTTPS 地址(如 `https://ip_or_domain/xxxx.git`),原因是目标主机名与备用证书主题名称不匹配。这通常是因为服务器的 SSL 证书配置不正确或客户端的证书验证设置有问题。建议检查服务器的 SSL 证书配置,确保其包含正确的主机名,并确认客户端的证书信任库已更新。此外,可以通过临时禁用 SSL 验证来排查问题,但请注意这会降低安全性。 ... [详细]
  • 【问题】在Android开发中,当为EditText添加TextWatcher并实现onTextChanged方法时,会遇到一个问题:即使只对EditText进行一次修改(例如使用删除键删除一个字符),该方法也会被频繁触发。这不仅影响性能,还可能导致逻辑错误。本文将探讨这一问题的原因,并提供有效的解决方案,包括使用Handler或计时器来限制方法的调用频率,以及通过自定义TextWatcher来优化事件处理,从而提高应用的稳定性和用户体验。 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
  • 本文详细探讨了使用纯JavaScript开发经典贪吃蛇游戏的技术细节和实现方法。通过具体的代码示例,深入解析了游戏逻辑、动画效果及用户交互的实现过程,为开发者提供了宝贵的参考和实践经验。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 本文全面解析了JavaScript中的DOM操作,并提供了详细的实践指南。DOM节点(Node)通常代表一个标签、文本或HTML属性,每个节点都具有一个nodeType属性,用于标识其类型。文章深入探讨了DOM节点的创建、查询、修改和删除等操作,结合实际案例,帮助读者更好地理解和掌握DOM编程技术。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • 解决针织难题:R语言编程技巧与常见错误分析 ... [详细]
  • Apache Hadoop HDFS QJournalProtocol 中 getJournalCTime 方法的应用与代码实例分析 ... [详细]
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有