我實現了這個link中解釋的例子。但我用scala重寫它。但我得到java.lang.NoClassDefFoundError:org/eclipse/jetty/io/nio/AsyncConnection錯誤。帶嵌入碼頭的WebSockets
這裏是我的RoomWebSocketHandler類:
import java.io.IOException
import javax.servlet.http.HttpServletRequest
import org.eclipse.jetty.websocket.WebSocket.Connection
import org.eclipse.jetty.websocket.{WebSocket, WebSocketHandler}
import scala.collection.mutable
class RoomWebSocketHandler extends WebSocketHandler {
private val webSockets = new mutable.ArrayBuffer[StateWebSocket]()
override def doWebSocketConnect(request: HttpServletRequest, protocol: String): WebSocket = {
new StateWebSocket()
}
private class StateWebSocket extends WebSocket.OnTextMessage {
var connection: Connection = _
def onOpen(connection: Connection) {
this.connection = connection
webSockets += this
}
def onMessage(data: String) {
try {
for (webSocket <- webSockets) {
webSocket.connection.sendMessage(data)
}
} catch {
case x: IOException => this.connection.close()
}
}
def onClose(closeCode: Int, message: String) {
webSockets -= this
}
}
}
,這是我主要類:
import java.net.InetSocketAddress
import grizzled.slf4j.Logger
import org.eclipse.jetty.server.{Handler, Server}
import org.eclipse.jetty.server.handler.{DefaultHandler, HandlerList, ResourceHandler}
import org.eclipse.jetty.servlet.ServletContextHandler
object Main {
var jettyServer: Option[Server] = None
def startServer(): Unit = {
val LOCAL_PORT = 4041
logger.debug("startServer begin")
jettyServer match {
case Some(s) =>
logger.info("Server is already running")
logger.debug("startServer end")
return
case None =>
logger.info("Server is not running")
}
val server = new Server(new InetSocketAddress("127.0.0.1", LOCAL_PORT))
server.setStopAtShutdown(true)
val handlers = new HandlerList()
val roomWebSocketHandler = new RoomWebSocketHandler();
roomWebSocketHandler.setHandler(new DefaultHandler());
handlers.setHandlers(Array[Handler](roomWebSocketHandler, new DefaultHandler()))
server.setHandler(handlers)
logger.debug("Starting jetty-server")
jettyServer = Some(server)
server.start()
logger.info("Server started on port: " + LOCAL_PORT)
logger.debug("startServer end")
}
def main(args: Array[String]): Unit = {
startServer()
}
}
這裏是我的依賴關係:
dependencies {
compile 'org.slf4j:slf4j-api:1.7.12'
compile 'ch.qos.logback:logback-classic:1.1.3'
compile 'com.h2database:h2:1.4.188'
compile 'org.clapper:grizzled-slf4j_2.11:1.0.2'
compile 'org.eclipse.jetty:jetty-webapp:9.3.3.v20150827'
compile 'org.eclipse.jetty:jetty-websocket:8.1.17.v20150415'
compile 'org.eclipse.jetty:jetty-http:8.1.17.v20150415'
compile 'org.eclipse.jetty:jetty-io:8.1.17.v20150415'
compile 'org.eclipse.jetty:jetty-util:8.1.17.v20150415'
compile 'org.eclipse.jetty:jetty-continuation:8.1.17.v20150415'
compile 'org.eclipse.jetty:jetty-server:8.1.17.v20150415'
compile 'org.eclipse.jetty:jetty-jmx:8.1.17.v20150415'
compile 'commons-cli:commons-cli:1.3.1'
compile 'org.scala-lang:scala-library:2.11.7'
runtime 'javax.servlet:javax.servlet-api:3.1.0'
testCompile 'org.scalacheck:scalacheck_2.11:1.12.4'
}
錯誤:
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jetty/io/nio/AsyncConnection
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.jetty.websocket.WebSocketHandler.<init>(WebSocketHandler.java:32)
at mypackage.RoomWebSocketHandler.<init>(RoomStateWebSocketHandler.scala:15)
at mypackage.Main$.startServer(Main.scala:48)
at mypackage.Main$.main(Main.scala:109)
at mypackage.Main.main(Main.scala)
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.io.nio.AsyncConnection
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 29 more
[碼頭8是EOL(壽命結束)](https://dev.eclipse.org/mhonarc /lists/jetty-announce/msg00069.html),它也只支持websocket草稿規範和初始最終RFC6455。大多數瀏覽器已經對WebSocket協議實現了額外的要求,現在呈現Jetty 8實現不受支持。升級到Jetty 9.x以獲取當前和受支持的WebSocket實現。 –