342504 Scanner Listener
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2999 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
e5bad59c14
commit
d3c5eddd79
|
@ -1,3 +1,6 @@
|
||||||
|
jetty-7.4.0-SNAPSHOT
|
||||||
|
+ 342504 Scanner Listener
|
||||||
|
|
||||||
jetty-7.4.0.RC0
|
jetty-7.4.0.RC0
|
||||||
+ 324110 Added test harnesses for merging of QueryStrings.
|
+ 324110 Added test harnesses for merging of QueryStrings.
|
||||||
+ 337685 Update websocket API in preparation for draft -07
|
+ 337685 Update websocket API in preparation for draft -07
|
||||||
|
|
|
@ -175,12 +175,6 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A
|
||||||
return _deploymentManager;
|
return _deploymentManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Deprecated
|
|
||||||
public Resource getMonitoredDir()
|
|
||||||
{
|
|
||||||
return _monitoredDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public Resource getMonitoredDirResource()
|
public Resource getMonitoredDirResource()
|
||||||
|
@ -212,30 +206,18 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A
|
||||||
_deploymentManager = deploymentManager;
|
_deploymentManager = deploymentManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @deprecated use {@link #setMonitoredDirResource(Resource)}
|
|
||||||
*/
|
|
||||||
public void setMonitoredDir(Resource dir)
|
|
||||||
{
|
|
||||||
setMonitoredDirResource(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
|
||||||
* @deprecated use {@link #setMonitoredDirName(String)}
|
|
||||||
*/
|
|
||||||
public void setMonitoredDir(String dir)
|
|
||||||
{
|
|
||||||
setMonitoredDirName(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public void setMonitoredDirResource(Resource contextsDir)
|
public void setMonitoredDirResource(Resource contextsDir)
|
||||||
{
|
{
|
||||||
_monitoredDir = contextsDir;
|
_monitoredDir = contextsDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public void addScannerListener(Scanner.Listener listener)
|
||||||
|
{
|
||||||
|
_scanner.addListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param dir
|
* @param dir
|
||||||
|
|
|
@ -16,9 +16,14 @@
|
||||||
package org.eclipse.jetty.deploy.providers;
|
package org.eclipse.jetty.deploy.providers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.deploy.AppProvider;
|
||||||
|
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||||
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
|
||||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||||
|
import org.eclipse.jetty.util.Scanner;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
|
@ -33,6 +38,8 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
@Rule
|
@Rule
|
||||||
public TestingDir testdir = new TestingDir();
|
public TestingDir testdir = new TestingDir();
|
||||||
private static XmlConfiguredJetty jetty;
|
private static XmlConfiguredJetty jetty;
|
||||||
|
private final AtomicInteger _scans = new AtomicInteger();
|
||||||
|
private int _providers;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupEnvironment() throws Exception
|
public void setupEnvironment() throws Exception
|
||||||
|
@ -46,6 +53,24 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
|
|
||||||
// Start it
|
// Start it
|
||||||
jetty.start();
|
jetty.start();
|
||||||
|
|
||||||
|
// monitor tick
|
||||||
|
DeploymentManager dm = jetty.getServer().getBeans(DeploymentManager.class).get(0);
|
||||||
|
for (AppProvider provider : dm.getAppProviders())
|
||||||
|
{
|
||||||
|
if (provider instanceof ScanningAppProvider)
|
||||||
|
{
|
||||||
|
_providers++;
|
||||||
|
((ScanningAppProvider)provider).addScannerListener(new Scanner.ScanListener()
|
||||||
|
{
|
||||||
|
public void scan()
|
||||||
|
{
|
||||||
|
_scans.incrementAndGet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -55,6 +80,23 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
jetty.stop();
|
jetty.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void waitForDirectoryScan()
|
||||||
|
{
|
||||||
|
int scan=_scans.get()+2*_providers;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(200);
|
||||||
|
}
|
||||||
|
catch(InterruptedException e)
|
||||||
|
{
|
||||||
|
Log.warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(_scans.get()<scan);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple webapp deployment after startup of server.
|
* Simple webapp deployment after startup of server.
|
||||||
*/
|
*/
|
||||||
|
@ -64,7 +106,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
||||||
jetty.copyContext("foo.xml","foo.xml");
|
jetty.copyContext("foo.xml","foo.xml");
|
||||||
|
|
||||||
jetty.waitForDirectoryScan();
|
waitForDirectoryScan();
|
||||||
|
|
||||||
jetty.assertWebAppContextsExists("/foo");
|
jetty.assertWebAppContextsExists("/foo");
|
||||||
}
|
}
|
||||||
|
@ -78,13 +120,13 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
||||||
jetty.copyContext("foo.xml","foo.xml");
|
jetty.copyContext("foo.xml","foo.xml");
|
||||||
|
|
||||||
jetty.waitForDirectoryScan();
|
waitForDirectoryScan();
|
||||||
|
|
||||||
jetty.assertWebAppContextsExists("/foo");
|
jetty.assertWebAppContextsExists("/foo");
|
||||||
|
|
||||||
jetty.removeContext("foo.xml");
|
jetty.removeContext("foo.xml");
|
||||||
|
|
||||||
jetty.waitForDirectoryScan();
|
waitForDirectoryScan();
|
||||||
|
|
||||||
// FIXME: hot undeploy with removal not working! - jetty.assertNoWebAppContexts();
|
// FIXME: hot undeploy with removal not working! - jetty.assertNoWebAppContexts();
|
||||||
}
|
}
|
||||||
|
@ -98,7 +140,7 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
jetty.copyWebapp("foo-webapp-1.war","foo.war");
|
||||||
jetty.copyContext("foo.xml","foo.xml");
|
jetty.copyContext("foo.xml","foo.xml");
|
||||||
|
|
||||||
jetty.waitForDirectoryScan();
|
waitForDirectoryScan();
|
||||||
|
|
||||||
jetty.assertWebAppContextsExists("/foo");
|
jetty.assertWebAppContextsExists("/foo");
|
||||||
|
|
||||||
|
@ -111,8 +153,8 @@ public class ScanningAppProviderRuntimeUpdatesTest
|
||||||
jetty.copyWebapp("foo-webapp-2.war","foo.war");
|
jetty.copyWebapp("foo-webapp-2.war","foo.war");
|
||||||
|
|
||||||
// This should result in the existing foo.war being replaced with the new foo.war
|
// This should result in the existing foo.war being replaced with the new foo.war
|
||||||
jetty.waitForDirectoryScan();
|
waitForDirectoryScan();
|
||||||
jetty.waitForDirectoryScan();
|
waitForDirectoryScan();
|
||||||
jetty.assertWebAppContextsExists("/foo");
|
jetty.assertWebAppContextsExists("/foo");
|
||||||
|
|
||||||
// Test that webapp response contains "-2"
|
// Test that webapp response contains "-2"
|
||||||
|
|
|
@ -431,18 +431,4 @@ public class XmlConfiguredJetty
|
||||||
_server.stop();
|
_server.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void waitForDirectoryScan()
|
|
||||||
{
|
|
||||||
int ms = 2000;
|
|
||||||
System.out.printf("Waiting %d milliseconds for AppProvider to process directory scan ...%n",ms);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Thread.sleep(ms);
|
|
||||||
}
|
|
||||||
catch (InterruptedException ignore)
|
|
||||||
{
|
|
||||||
/* ignore */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<Array type="org.eclipse.jetty.deploy.AppProvider">
|
<Array type="org.eclipse.jetty.deploy.AppProvider">
|
||||||
<Item>
|
<Item>
|
||||||
<New class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
<New class="org.eclipse.jetty.deploy.providers.ContextProvider">
|
||||||
<Set name="monitoredDir"><SystemProperty name="jetty.home" />/contexts</Set>
|
<Set name="monitoredDirName"><SystemProperty name="jetty.home" />/contexts</Set>
|
||||||
<Set name="scanInterval">1</Set>
|
<Set name="scanInterval">1</Set>
|
||||||
<Set name="configurationManager">
|
<Set name="configurationManager">
|
||||||
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
|
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
</Item>
|
</Item>
|
||||||
<Item>
|
<Item>
|
||||||
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
||||||
<Set name="monitoredDir"><SystemProperty name="jetty.home" />/webapps</Set>
|
<Set name="monitoredDirName"><SystemProperty name="jetty.home" />/webapps</Set>
|
||||||
<Set name="scanInterval">1</Set>
|
<Set name="scanInterval">1</Set>
|
||||||
<Set name="contextXmlDir"><SystemProperty name="jetty.home" />/contexts</Set>
|
<Set name="contextXmlDir"><SystemProperty name="jetty.home" />/contexts</Set>
|
||||||
</New>
|
</New>
|
||||||
|
|
|
@ -104,6 +104,10 @@ public class Scanner extends AbstractLifeCycle
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ScanListener extends Listener
|
||||||
|
{
|
||||||
|
public void scan();
|
||||||
|
}
|
||||||
|
|
||||||
public interface DiscreteListener extends Listener
|
public interface DiscreteListener extends Listener
|
||||||
{
|
{
|
||||||
|
@ -391,6 +395,23 @@ public class Scanner extends AbstractLifeCycle
|
||||||
_prevScan.clear();
|
_prevScan.clear();
|
||||||
_prevScan.putAll(_currentScan);
|
_prevScan.putAll(_currentScan);
|
||||||
reportScanEnd(_scanCount);
|
reportScanEnd(_scanCount);
|
||||||
|
|
||||||
|
for (Listener l : _listeners)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (l instanceof ScanListener)
|
||||||
|
((ScanListener)l).scan();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.warn(e);
|
||||||
|
}
|
||||||
|
catch (Error e)
|
||||||
|
{
|
||||||
|
Log.warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.TypeUtil;
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
|
@ -18,8 +19,9 @@ public class TestServer extends Server
|
||||||
|
|
||||||
WebSocket _websocket;
|
WebSocket _websocket;
|
||||||
SelectChannelConnector _connector;
|
SelectChannelConnector _connector;
|
||||||
WebSocketHandler _handler;
|
WebSocketHandler _wsHandler;
|
||||||
ConcurrentLinkedQueue<TestWebSocket> _webSockets = new ConcurrentLinkedQueue<TestWebSocket>();
|
ResourceHandler _rHandler;
|
||||||
|
ConcurrentLinkedQueue<TestWebSocket> _broadcast = new ConcurrentLinkedQueue<TestWebSocket>();
|
||||||
|
|
||||||
public TestServer(int port)
|
public TestServer(int port)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +29,7 @@ public class TestServer extends Server
|
||||||
_connector.setPort(port);
|
_connector.setPort(port);
|
||||||
|
|
||||||
addConnector(_connector);
|
addConnector(_connector);
|
||||||
_handler = new WebSocketHandler()
|
_wsHandler = new WebSocketHandler()
|
||||||
{
|
{
|
||||||
public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
|
public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
|
||||||
{
|
{
|
||||||
|
@ -56,20 +58,39 @@ public class TestServer extends Server
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setHandler(_handler);
|
setHandler(_wsHandler);
|
||||||
|
|
||||||
|
_rHandler=new ResourceHandler();
|
||||||
|
_rHandler.setDirectoriesListed(true);
|
||||||
|
_rHandler.setResourceBase(".");
|
||||||
|
_wsHandler.setHandler(_rHandler);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
public boolean isVerbose()
|
public boolean isVerbose()
|
||||||
{
|
{
|
||||||
return _verbose;
|
return _verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
public void setVerbose(boolean verbose)
|
public void setVerbose(boolean verbose)
|
||||||
{
|
{
|
||||||
_verbose = verbose;
|
_verbose = verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public void setResourceBase(String dir)
|
||||||
|
{
|
||||||
|
_rHandler.setResourceBase(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String getResourceBase()
|
||||||
|
{
|
||||||
|
return _rHandler.getResourceBase();
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
class TestWebSocket implements WebSocket, WebSocket.OnFrame, WebSocket.OnBinaryMessage, WebSocket.OnTextMessage, WebSocket.OnControl
|
class TestWebSocket implements WebSocket, WebSocket.OnFrame, WebSocket.OnBinaryMessage, WebSocket.OnTextMessage, WebSocket.OnControl
|
||||||
|
@ -84,12 +105,14 @@ public class TestServer extends Server
|
||||||
public void onConnect(Connection connection)
|
public void onConnect(Connection connection)
|
||||||
{
|
{
|
||||||
_connection = connection;
|
_connection = connection;
|
||||||
_webSockets.add(this);
|
if (_verbose)
|
||||||
|
System.err.printf("%s#onConnect %s\n",this.getClass().getSimpleName(),connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDisconnect(int code,String message)
|
public void onDisconnect(int code,String message)
|
||||||
{
|
{
|
||||||
_webSockets.remove(this);
|
if (_verbose)
|
||||||
|
System.err.printf("%s#onDisonnect %d %s\n",this.getClass().getSimpleName(),code,message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onFrame(byte flags, byte opcode, byte[] data, int offset, int length)
|
public boolean onFrame(byte flags, byte opcode, byte[] data, int offset, int length)
|
||||||
|
@ -160,11 +183,25 @@ public class TestServer extends Server
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
class TestEchoBroadcastWebSocket extends TestWebSocket
|
class TestEchoBroadcastWebSocket extends TestWebSocket
|
||||||
{
|
{
|
||||||
|
@Override
|
||||||
|
public void onConnect(Connection connection)
|
||||||
|
{
|
||||||
|
super.onConnect(connection);
|
||||||
|
_broadcast.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect(int code,String message)
|
||||||
|
{
|
||||||
|
super.onDisconnect(code,message);
|
||||||
|
_broadcast.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(byte[] data, int offset, int length)
|
public void onMessage(byte[] data, int offset, int length)
|
||||||
{
|
{
|
||||||
super.onMessage(data,offset,length);
|
super.onMessage(data,offset,length);
|
||||||
for (TestWebSocket ws : _webSockets)
|
for (TestWebSocket ws : _broadcast)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -172,6 +209,7 @@ public class TestServer extends Server
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
_broadcast.remove(ws);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +219,7 @@ public class TestServer extends Server
|
||||||
public void onMessage(final String data)
|
public void onMessage(final String data)
|
||||||
{
|
{
|
||||||
super.onMessage(data);
|
super.onMessage(data);
|
||||||
for (TestWebSocket ws : _webSockets)
|
for (TestWebSocket ws : _broadcast)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -189,6 +227,7 @@ public class TestServer extends Server
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
|
_broadcast.remove(ws);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,17 +325,19 @@ public class TestServer extends Server
|
||||||
private static void usage()
|
private static void usage()
|
||||||
{
|
{
|
||||||
System.err.println("java -cp CLASSPATH "+TestServer.class+" [ OPTIONS ]");
|
System.err.println("java -cp CLASSPATH "+TestServer.class+" [ OPTIONS ]");
|
||||||
System.err.println(" -p|--port PORT ");
|
System.err.println(" -p|--port PORT (default 8080)");
|
||||||
System.err.println(" -v|--verbose ");
|
System.err.println(" -v|--verbose ");
|
||||||
|
System.err.println(" -d|--docroot file (default '.')");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args)
|
public static void main(String... args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int port=8080;
|
int port=8080;
|
||||||
boolean verbose=false;
|
boolean verbose=false;
|
||||||
|
String docroot=".";
|
||||||
|
|
||||||
for (int i=0;i<args.length;i++)
|
for (int i=0;i<args.length;i++)
|
||||||
{
|
{
|
||||||
|
@ -305,6 +346,8 @@ public class TestServer extends Server
|
||||||
port=Integer.parseInt(args[++i]);
|
port=Integer.parseInt(args[++i]);
|
||||||
else if ("-v".equals(a)||"--verbose".equals(a))
|
else if ("-v".equals(a)||"--verbose".equals(a))
|
||||||
verbose=true;
|
verbose=true;
|
||||||
|
else if ("-d".equals(a)||"--docroot".equals(a))
|
||||||
|
docroot=args[++i];
|
||||||
else if (a.startsWith("-"))
|
else if (a.startsWith("-"))
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
@ -312,6 +355,7 @@ public class TestServer extends Server
|
||||||
|
|
||||||
TestServer server = new TestServer(port);
|
TestServer server = new TestServer(port);
|
||||||
server.setVerbose(verbose);
|
server.setVerbose(verbose);
|
||||||
|
server.setResourceBase(docroot);
|
||||||
server.start();
|
server.start();
|
||||||
server.join();
|
server.join();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
|
||||||
|
<html><head>
|
||||||
|
<title>WebSocket Chat</title>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
|
||||||
|
if (!window.WebSocket)
|
||||||
|
alert("WebSocket not supported by this browser");
|
||||||
|
|
||||||
|
function $() { return document.getElementById(arguments[0]); }
|
||||||
|
function $F() { return document.getElementById(arguments[0]).value; }
|
||||||
|
|
||||||
|
function getKeyCode(ev) { if (window.event) return window.event.keyCode; return ev.keyCode; }
|
||||||
|
|
||||||
|
var room = {
|
||||||
|
join: function(name) {
|
||||||
|
this._username=name;
|
||||||
|
var location = document.location.toString().replace('http://','ws://').replace('https://','wss://');
|
||||||
|
this._ws=new WebSocket(location,"org.ietf.websocket.test-echo-broadcast");
|
||||||
|
this._ws.onopen=this._onopen;
|
||||||
|
this._ws.onmessage=this._onmessage;
|
||||||
|
this._ws.onclose=this._onclose;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onopen: function(){
|
||||||
|
$('join').className='hidden';
|
||||||
|
$('joined').className='';
|
||||||
|
$('phrase').focus();
|
||||||
|
room._send(room._username,'has joined!');
|
||||||
|
},
|
||||||
|
|
||||||
|
_send: function(user,message){
|
||||||
|
user=user.replace(':','_');
|
||||||
|
if (this._ws)
|
||||||
|
this._ws.send(user+':'+message);
|
||||||
|
},
|
||||||
|
|
||||||
|
chat: function(text) {
|
||||||
|
if (text != null && text.length>0 )
|
||||||
|
room._send(room._username,text);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onmessage: function(m) {
|
||||||
|
if (m.data){
|
||||||
|
var c=m.data.indexOf(':');
|
||||||
|
var from=m.data.substring(0,c).replace('<','<').replace('>','>');
|
||||||
|
var text=m.data.substring(c+1).replace('<','<').replace('>','>');
|
||||||
|
|
||||||
|
var chat=$('chat');
|
||||||
|
var spanFrom = document.createElement('span');
|
||||||
|
spanFrom.className='from';
|
||||||
|
spanFrom.innerHTML=from+': ';
|
||||||
|
var spanText = document.createElement('span');
|
||||||
|
spanText.className='text';
|
||||||
|
spanText.innerHTML=text;
|
||||||
|
var lineBreak = document.createElement('br');
|
||||||
|
chat.appendChild(spanFrom);
|
||||||
|
chat.appendChild(spanText);
|
||||||
|
chat.appendChild(lineBreak);
|
||||||
|
chat.scrollTop = chat.scrollHeight - chat.clientHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onclose: function(m) {
|
||||||
|
this._ws=null;
|
||||||
|
$('join').className='';
|
||||||
|
$('joined').className='hidden';
|
||||||
|
$('username').focus();
|
||||||
|
$('chat').innerHTML='';
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style type='text/css'>
|
||||||
|
div { border: 0px solid black; }
|
||||||
|
div#chat { clear: both; width: 40em; height: 20ex; overflow: auto; background-color: #f0f0f0; padding: 4px; border: 1px solid black; }
|
||||||
|
div#input { clear: both; width: 40em; padding: 4px; background-color: #e0e0e0; border: 1px solid black; border-top: 0px }
|
||||||
|
input#phrase { width:30em; background-color: #e0f0f0; }
|
||||||
|
input#username { width:14em; background-color: #e0f0f0; }
|
||||||
|
div.hidden { display: none; }
|
||||||
|
span.from { font-weight: bold; }
|
||||||
|
span.alert { font-style: italic; }
|
||||||
|
</style>
|
||||||
|
</head><body>
|
||||||
|
<div id='chat'></div>
|
||||||
|
<div id='input'>
|
||||||
|
<div id='join' >
|
||||||
|
Username: <input id='username' type='text'/><input id='joinB' class='button' type='submit' name='join' value='Join'/>
|
||||||
|
</div>
|
||||||
|
<div id='joined' class='hidden'>
|
||||||
|
Chat: <input id='phrase' type='text'/>
|
||||||
|
<input id='sendB' class='button' type='submit' name='join' value='Send'/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type='text/javascript'>
|
||||||
|
$('username').setAttribute('autocomplete','OFF');
|
||||||
|
$('username').onkeyup = function(ev) { var keyc=getKeyCode(ev); if (keyc==13 || keyc==10) { room.join($F('username')); return false; } return true; } ;
|
||||||
|
$('joinB').onclick = function(event) { room.join($F('username')); return false; };
|
||||||
|
$('phrase').setAttribute('autocomplete','OFF');
|
||||||
|
$('phrase').onkeyup = function(ev) { var keyc=getKeyCode(ev); if (keyc==13 || keyc==10) { room.chat($F('phrase')); $('phrase').value=''; return false; } return true; };
|
||||||
|
$('sendB').onclick = function(event) { room.chat($F('phrase')); $('phrase').value=''; return false; };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This is a demonstration of the Jetty websocket server.
|
||||||
|
</p>
|
||||||
|
</body></html>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue