undertow服务器分析_使用undertow构建和测试Websocket服务器
undertow服務(wù)器分析
即將發(fā)布的JBoss Application Server版本將不再使用Tomcat作為集成的Web服務(wù)器,而是將其替換為undertow 。 undertow的體系結(jié)構(gòu)基于可通過Builder API動(dòng)態(tài)添加到服務(wù)器的處理程序。 這種方法類似于在Node.js中構(gòu)造Web服務(wù)器的方式。 它使開發(fā)人員可以輕松地將Underwow Web服務(wù)器嵌入到其應(yīng)用程序中。 由于功能是通過Builder API完成的,因此只能添加一個(gè)人的應(yīng)用程序中真正需要的功能。 除此之外,undertow支持WebSockets和版本3.1中的Servlet API。 它可以作為阻塞服務(wù)器或非阻塞服務(wù)器運(yùn)行,據(jù)說,首次測(cè)試已經(jīng)證明Undertow是用Java編寫的最快的Web服務(wù)器。
由于所有這些聽起來很有希望,所以讓我們嘗試設(shè)置一個(gè)簡單的websocket服務(wù)器。 和往常一樣,我們從創(chuàng)建一個(gè)簡單的Java項(xiàng)目開始,并添加undertow maven依賴項(xiàng):
<dependency><groupId>io.undertow</groupId><artifactId>undertow-core</artifactId><version>1.0.0.Beta20</version> </dependency>使用undertow的Builder API,我們的buildAndStartServer()方法如下所示:
public void buildAndStartServer(int port, String host) {server = Undertow.builder().addListener(port, host).setHandler(getWebSocketHandler()).build();server.start(); }我們只添加一個(gè)偵聽器,該偵聽器指定用于偵聽傳入連接的端口和主機(jī),然后添加一個(gè)websocket處理程序。 由于websocket處理程序代碼更加全面,我將其放入自己的方法中:
private PathHandler getWebSocketHandler() {return path().addPath("/websocket", websocket(new WebSocketConnectionCallback() {@Overridepublic void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) {channel.getReceiveSetter().set(new AbstractReceiveListener() {@Overrideprotected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) {String data = message.getData();lastReceivedMessage = data;LOGGER.info("Received data: "+data);WebSockets.sendText(data, channel, null);}});channel.resumeReceives();}})).addPath("/", resource(new ClassPathResourceManager(WebSocketServer.class.getClassLoader(), WebSocketServer.class.getPackage())).addWelcomeFiles("index.html")); }讓我們逐行瀏覽此代碼段。 首先,我們添加一個(gè)新路徑:/ websocket。 addPath()方法的第二個(gè)參數(shù)使我們可以指定要用于此路徑的協(xié)議類型。 在我們的例子中,我們創(chuàng)建一個(gè)新的WebSocket。 匿名實(shí)現(xiàn)有一個(gè)onConnect()方法,在其中我們?cè)O(shè)置了AbstractReceiveListener的實(shí)現(xiàn)。 在這里,我們有一個(gè)方便的方法onFullTextMessage(),當(dāng)客戶端向我們發(fā)送文本消息時(shí)會(huì)調(diào)用該方法。 調(diào)用getData()將獲取我們收到的實(shí)際消息。 在這個(gè)簡單的示例中,我們只是將該字符串回顯給客戶端,以驗(yàn)證從客戶端到服務(wù)器以及向后的往返是否有效。
為了執(zhí)行一些簡單的手動(dòng)測(cè)試,我們還在路徑/下添加了第二個(gè)資源,該資源提供一些靜態(tài)HTML和JavaScript文件。 包含這些文件的目錄作為ClassPathResourceManager的實(shí)例給出。 當(dāng)客戶端請(qǐng)求路徑/時(shí),addWelcomeFiles()的調(diào)用告訴undertow服務(wù)器哪個(gè)文件。
index.html看起來像這樣:
</pre> <html> <head><title>Web Socket Test</title></head> <body><script src="jquery-2.0.3.min.js"></script><script src="jquery.gracefulWebSocket.js"></script><script src="websocket.js"></script><form onsubmit="return false;"><input type="text" name="message" value="Hello, World!"/><input type="button" value="Send Web Socket Data" onclick="send(this.form.message.value)"/></form><div id="output"></div> </body> </html> <pre>我們JavaScript代碼被換成websocket.js文件。 我們使用jquery和jquery-Plugin gracefulWebSocket來簡化客戶端開發(fā):
var ws = $.gracefulWebSocket("ws://127.0.0.1:8080/websocket"); ws.onmessage = function(event) {var messageFromServer = event.data;$('#output').append('Received: '+messageFromServer+''); }function send(message) {ws.send(message); }通過調(diào)用$ .gracefulWebSocket()創(chuàng)建WebSocket對(duì)象后,我們可以為傳入消息注冊(cè)回調(diào)函數(shù)。 在此方法中,我們僅將消息字符串附加到頁面的DOM。 send()方法只是對(duì)gracefulWebSocket的send()方法的調(diào)用。
現(xiàn)在啟動(dòng)應(yīng)用程序并在Web瀏覽器中打開URL http://127.0.0.1:8080/時(shí) ,我們將看到以下頁面:
輸入一些字符串并單擊“發(fā)送Web套接字?jǐn)?shù)據(jù)”按鈕,將消息發(fā)送到服務(wù)器,服務(wù)器作為響應(yīng)將其回顯給客戶端。
既然我們知道一切都會(huì)按預(yù)期進(jìn)行,那么我們想使用junit測(cè)試用例來保護(hù)我們的代碼免于回歸。 作為一個(gè)websocket客戶,我選擇了jetty-websocket庫:
<dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-websocket</artifactId><version>8.1.0.RC5</version><scope>test</scope> </dependency>在測(cè)試案例中,我們構(gòu)建并啟動(dòng)websocket服務(wù)器以打開到websocket端口的新連接。 jetty-websocket的WebSocket實(shí)現(xiàn)允許我們?yōu)閛pen和close事件實(shí)現(xiàn)兩種回調(diào)方法。 在打開的回調(diào)中,我們將測(cè)試消息發(fā)送給客戶端。 其余代碼等待連接建立,關(guān)閉連接并斷言服務(wù)器已收到消息:
@Test public void testStartAndBuild() throws Exception {subject = new WebSocketServer();subject.buildAndStartServer(8080, "127.0.0.1");WebSocketClient client = new WebSocketClient();Future connectionFuture = client.open(new URI("ws://localhost:8080/websocket"), new WebSocket() {@Overridepublic void onOpen(Connection connection) {LOGGER.info("onOpen");try {connection.sendMessage("TestMessage");} catch (IOException e) {LOGGER.error("Failed to send message: "+e.getMessage(), e);}}@Overridepublic void onClose(int i, String s) {LOGGER.info("onClose");}});WebSocket.Connection connection = connectionFuture.get(2, TimeUnit.SECONDS);assertThat(connection, is(notNullValue()));connection.close();subject.stopServer();Thread.sleep(1000);assertThat(subject.lastReceivedMessage, is("TestMessage")); }- 和往常一樣,您可以在github上找到源代碼。
結(jié)論
Undertow的Builder API使構(gòu)建Websocket服務(wù)器和滿足您需求的嵌入式Web服務(wù)器變得容易。 這也簡化了自動(dòng)測(cè)試,因?yàn)槟恍枰诩蓽y(cè)試之前和之后啟動(dòng)和停止服務(wù)器的任何特定maven插件。 除此之外,jQuery插件jquery-graceful-websocket允許您僅使用幾行代碼就可以通過websocket發(fā)送和接收消息。
翻譯自: https://www.javacodegeeks.com/2013/11/building-and-testing-a-websocket-server-with-undertow.html
undertow服務(wù)器分析
總結(jié)
以上是生活随笔為你收集整理的undertow服务器分析_使用undertow构建和测试Websocket服务器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果发布 iPadOS 17 正式版:引
- 下一篇: 苹果提高 iOS 17 安全性:Safa