我下载了一台在我的PC上运行的简单的Java websocket echo服务器(Windows 10)。该应用程序在本地Tomcat服务器上运行(我的PC的IP地址为192.168.178.10)。
要在浏览器中启动应用程序,使用的命令是:
http://localhost:8080/echochamber/
如果我通过浏览器连接它,一切正常。但是,如果我使用NodeMCU(ESP8266),它将拒绝连接。我尝试了一个不同的外部网站:
echo.websocket.org
NodeMCU表现完美无瑕。所以我的第一个猜测是我以错误的方式连接到我的本地服务器。但我现在有点迷失了。为什么我无法连接到本地运行的服务器,而是轻松连接到外部服务器?我在哪里弄错了?
提前致谢。
Java Web服务器代码
一个班级:
package echochamber;
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
/**
* @ServerEndpoint gives the relative name for the end point
* This will be accessed via ws://localhost:8080/EchoChamber/echo
* Where "localhost" is the address of the host,
* "EchoChamber" is the name of the package
* and "echo" is the address to access this class from the server
*/
@ServerEndpoint("/echo")
public class EchoServer {
/**
* @OnOpen allows us to intercept the creation of a new session.
* The session class allows us to send data to the user.
* In the method onOpen, we'll let the user know that the handshake was
* successful.
*/
@OnOpen
public void onOpen(Session session){
System.out.println(session.getId() + " has opened a connection");
try {
session.getBasicRemote().sendText("Connection Established");
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* When a user sends a message to the server, this method will intercept the message
* and allow us to react to it. For now the message is read as a String.
*/
@OnMessage
public void onMessage(String message, Session session){
System.out.println("Message from " + session.getId() + ": " + message);
try {
session.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* The user closes the connection.
*
* Note: you can't send messages to the client from this method
*/
@OnClose
public void onClose(Session session){
System.out.println("Session " +session.getId()+" has ended");
}
}
和一个html文件:
<!DOCTYPE html>
<html>
<head>
<title>Echo Chamber</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<div>
<input type="text" id="messageinput"/>
</div>
<div>
<button type="button" onclick="openSocket();" >Open</button>
<button type="button" onclick="send();" >Send</button>
<button type="button" onclick="closeSocket();" >Close</button>
</div>
<!-- Server responses get written here -->
<div id="messages"></div>
<!-- Script to utilise the WebSocket -->
<script type="text/javascript">
var webSocket;
var messages = document.getElementById("messages");
function openSocket(){
// Ensures only one connection is open at a time
if(webSocket !== undefined && webSocket.readyState !== WebSocket.CLOSED){
writeResponse("WebSocket is already opened.");
return;
}
// Create a new instance of the websocket
webSocket = new WebSocket("ws://localhost:8080/echochamber/echo");
/**
* Binds functions to the listeners for the websocket.
*/
webSocket.onopen = function(event){
// For reasons I can't determine, onopen gets called twice
// and the first time event.data is undefined.
// Leave a comment if you know the answer.
if(event.data === undefined)
return;
writeResponse(event.data);
};
webSocket.onmessage = function(event){
writeResponse(event.data);
};
webSocket.onclose = function(event){
writeResponse("Connection closed");
};
}
/**
* Sends the value of the text input to the server
*/
function send(){
var text = document.getElementById("messageinput").value;
webSocket.send(text);
}
function closeSocket(){
webSocket.close();
}
function writeResponse(text){
messages.innerHTML += "<br/>" + text;
}
</script>
</body>
</html>
在 nodeMCU 上,我使用的代码如下:
/*
* WebSocketClient.ino
*
* Created on: 24.05.2015
*
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h>
#include <Hash.h>
char SSID[] = "********";
char PASSWORD[] = "********";
ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
#define USE_SERIAL Serial
#define VERIFY // if defined goes to echo.websocket.org
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
char message[100];
switch (type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[WSc] Disconnected!\n");
break;
case WStype_CONNECTED: {
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
// send message to server when Connected
webSocket.sendTXT("Connected");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
//send message to server
sprintf(message, "millis count = %d", millis());
webSocket.sendTXT(message);
delay(1000);
break;
case WStype_BIN:
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
hexdump(payload, length);
// send data to server
// webSocket.sendBIN(payload, length);
break;
}
}
void setup() {
// Serial setup
//USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);
// output all debug info
USE_SERIAL.setDebugOutput(true);
for (uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
// connect to my local WiFi gateway
WiFiMulti.addAP(SSID, PASSWORD);
// WiFi.disconnect();
while (WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
// server address, port and URL
#ifdef VERIFY
webSocket.begin("echo.websocket.org", 80, "/");
#else
webSocket.begin("192.168.178.10", 80, "/echochamber");
#endif
// initialte our event handler
webSocket.onEvent(webSocketEvent);
// use HTTP Basic Authorization this is optional remove if not needed
// webSocket.setAuthorization("user", "Password");
// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
webSocket.
}
void loop() {
webSocket.loop();
}
如果我连接到echo.websocket.org,这就是输出:
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 2
cnt
connected with verelec_1, channel 1
dhcp client start...
[SETUP] BOOT WAIT 3...
[SETUP] BOOT WAIT 2...
[SETUP] BOOT WAIT 1...
ip:192.168.178.16,mask:255.255.255.0,gw:192.168.178.1
[WSc] Connected to url: /
[WSc] get text: Connected
[WSc] get text: millis count = 5363
[WSc] get text: millis count = 6480
[WSc] get text: millis count = 7602
[WSc] get text: millis count = 8729
[WSc] get text: millis count = 9854
[WSc] get text: millis count = 10968
[WSc] get text: millis count = 12096
[WSc] get text: millis count = 13243
[WSc] get text: millis count = 14369
[WSc] get text: millis count = 15905
[WSc] get text: millis count = 17021
[WSc] get text: millis count = 18135
[WSc] get text: millis count = 19251
[WSc] get text: millis count = 20365
[WSc] get text: millis count = 21482
[WSc] get text: millis count = 22597
[WSc] get text: millis count = 23712
[WSc] get text: millis count = 24828
[WSc] get text: millis count = 25945
[WSc] get text: millis count = 27059
[WSc] get text: millis count = 28173
[WSc] get text: millis count = 29313
[WSc] get text: millis count = 30427
[WSc] get text: millis count = 31545
[WSc] get text: millis count = 32661
答案 0 :(得分:0)
解决方案是将端口更改为8080并且工作正常