hi guys im trying implement an example of send file through websocket using sendBinary method . I`m deploying server code in Tomcat 8.0.20 and client code using tyrus 1.8.3 implementation/provider . There are my server and client class :
Server code :
package socket;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint("/chat")
public class Server {
#OnOpen
public void onOpen(Session session) {
}
#OnClose
public void onClose(Session session,CloseReason closeReason) {
}
#OnError
public void onError(Throwable throwable){
throwable.printStackTrace();
}
#OnMessage
public void message(String message, Session session) throws IOException {
}
#OnMessage
public void message(Session session,ByteBuffer byteBuffer) throws IOException {
System.out.println(" Binary received ... ");
}
}
Client code :
package br.com.jslsolucoes.socket.client;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import org.apache.commons.io.IOUtils;
#ClientEndpoint
public class Client {
private static CountDownLatch latch;
#OnOpen
public void onOpen(Session session) throws IOException {
InputStream inputStream = getClass().getResourceAsStream(
"/myvideo.wmv");
byte[] buffer = new byte[8 * 1024];
while (IOUtils.read(inputStream, buffer) != 0) {
session.getBasicRemote().sendBinary(ByteBuffer.wrap(buffer));
}
}
#OnClose
public void onClose(Session session,CloseReason closeReason) throws IOException {
latch.countDown();
}
#OnMessage
public void processMessage(String message) {
}
#OnError
public void onError(Throwable throwable){
throwable.printStackTrace();
}
public static void main(String[] args) throws DeploymentException,
IOException, InterruptedException {
latch = new CountDownLatch(1);
WebSocketContainer container = ContainerProvider
.getWebSocketContainer();
String uri = "ws://localhost:8081/socket/chat";
Client client = new Client();
container.connectToServer(client, URI.create(uri));
latch.await();
}
}
its works ok but while uploading after a time about 30 seconds an exception is launched :
java.io.ioexception : an existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:197)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379)
at org.apache.tomcat.util.net.NioChannel.read(NioChannel.java:140)
at org.apache.coyote.http11.upgrade.NioServletInputStream.fillReadBuffer(NioServletInputStream.java:136)
at org.apache.coyote.http11.upgrade.NioServletInputStream.doRead(NioServletInputStream.java:80)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.read(AbstractServletInputStream.java:124)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:51)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:203)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:654)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Someone can help me with this problem ?
Related
I am trying to run the rmi tutorial on oracles' website. I am able to run the server, but I receive an error running the client. The error I receive when try to run the client is a NotBoundException exception. How do I fix this error?
Below is the code and exception
Exception
Exception in thread "main" java.rmi.NotBoundException: Server
at java.rmi/sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:234)
at java.rmi/sun.rmi.registry.RegistryImpl_Skel.dispatch(RegistryImpl_Skel.java:133)
at java.rmi/sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:468)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:298)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
at java.rmi/sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:303)
at java.rmi/sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:279)
at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:380)
at java.rmi/sun.rmi.registry.RegistryImpl_Stub.lookup(RegistryImpl_Stub.java:123)
at rmi.Client.main(Client.java:13)
I use Server and Client with different project at Port 1212
here is Server
package De_1;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws RemoteException, AlreadyBoundException {
Registry r = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
ProductDAO productDAO = new ProductDAOImpl();
r.bind("Server", productDAO);
}
}
and here is Client
package rmi;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Client {
public static void main(String[] args) throws RemoteException, NotBoundException {
Registry r = LocateRegistry.getRegistry(1212);
ProductDAO productDAO = (ProductDAO) r.lookup("Server");
System.out.println("Hay nhap");
Scanner sc = new Scanner(System.in);
while (true) {
String command = sc.nextLine();
StringTokenizer stringTokenizer = new StringTokenizer(command);
String request = stringTokenizer.nextToken();
System.out.println(request);
switch (request) {
case "HELLO": {
productDAO.addProduct();
}
default:
break;
}
}
}
}
I am working on Websocket currently. So do I send and receive data using wss protocol? I am already using HTTP post and get but need to upgrade to wss. Please help. Thanks in advance
if you are using standalone applications (console app) I recommend you to use java-websocket or if it's a JavaEE WebApp, Example:
package org.hectorvent.gpstracking.websocket;
import org.hectorvent.gpstracking.restful.model.PdaGeoData;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Singleton;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#Singleton
#ServerEndpoint("/geodata")
public class WebSocketGmap {
private final Set<Session> clients = new HashSet();
#OnOpen
public void open(Session session) {
clients.add(session);
}
#OnMessage
public void onMessage(String message, Session session) {
// here you're going to received client messages.
}
#OnClose
public void close(Session session) {
clients.remove(session);
}
#OnError
public void onError(Throwable error) {
}
public void sendMessage(PdaGeoData pgd) {
for (Session client : clients) {
Future fu = client.getAsyncRemote()
.sendText(GsonUtils.toJson(pgd));
}
}
}
I'm working on an Web Application in which multiple users work on the same data (source is sql database)
I'm using
Netbeans 8.0.2
Tomcat 8.0.28
Maven 4.0.0
jquery-2.1.4
I want the server to push a message to all clients which have opened a WebSocket Connection to my server.
I found a lot of guides/tutorials on how to implement WebSockets but they all rely on the Client pushing something to the Server.
I just need the server to push a message to the Client.
Can any1 provide a short example on how to to this??
It just needs to be:
Client opens SocketConnection
JavaClass establishes connection
JavaClass method sends message/data to client
EDIT:
My setup right now:
On application startup I do the following:
startup.java
package com.mycompany.ssp;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import javax.servlet.ServletContextEvent;
public class Startup implements javax.servlet.ServletContextListener {
private static WebSocketServer socket_server = null;
// create singleton object Socket
getSocket();
public static WebSocketServer getSocket(){
if(socket_server == null) {
socket_server = new WebSocketServer();
}
return socket_server;
}
}
WebSocketServer.java
package com.mycompany.ssp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint(value = "/socket")
public class WebSocketServer {
private static final Logger LOGGER = Logger.getLogger(WebSocketServer.class.getName());
private List<Session> session_list = new ArrayList<Session>();
WebSocketServer socket_server = Startup.getSocket();
public WebSocketServer() {
}
#OnOpen
public void onOpen(Session session) {
LOGGER.log(Level.INFO, "New connection with client: {0}",
session.getId());
socket_server.session_list.add(session);
}
#OnMessage
public String onMessage(String message, Session session) {
LOGGER.log(Level.INFO, "New message from Client [{0}]: {1}",
new Object[] {session.getId(), message});
return "Server received [" + message + "]";
}
#OnClose
public void onClose(Session session) {
LOGGER.log(Level.INFO, "Close connection for client: {0}",
session.getId());
socket_server.session_list.remove(session);
}
#OnError
public void onError(Throwable exception, Session session) {
LOGGER.log(Level.INFO, "Error for client: {0}", session.getId());
}
public void send(String message) throws IOException{
for(Session session: socket_server.session_list){
session.getBasicRemote().sendText(message);
}
}
}
I get an Error when trying to start my application.
Why does it happen?
Well, the Method getSocket() loops multiple times and everytime after
socket_server = new WebSocketServer(); the variable socket_server is still null, which should be initialized though.
Netbeans Apache TomcatEE Log:
SEVERE [http-nio-8080-exec-1050] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class com.mycompany.ssp.Startup
java.lang.StackOverflowError
Does any1 have an idea why this is happening??
var websocket=new websocket(websocket_url);
Java Code
#ServerEndpoint(value = "/websocket/one")
public class WebsocketEndPoint {
public static List clients=new ArrayList();
#OnOpen
public void OnOpen(Session session, EndpointConfig config)
throws IOException {
//Save the endpoints session that opened the connection in List
}
#OnMessage
public void OnMessage(Session session, String message) {
}
#OnClose
public void OnClose(Session session, CloseReason reason) {
//remove from list
}
#OnError
public void OnError(Session session, Throwable throwable) {
}
}
}
3.
class Sender{
public void send(String message){
for(Session session:WebsocketEndPoint.clients){
session.getBasicRemote().sendText(message);
}
}
}
Hope this helps
And in Javascript u can use onMessage to get the message
I have written a Java RMI chat application. There are four classes and two interfaces. Here they are:
ChatClient
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Scanner;
com.za.tutorial.rmi.server.ChatServerIF;
public class ChatClient extends UnicastRemoteObject implements ChatClientIF,Runnable {
private ChatServerIF chatServer;
private String name = null;
protected ChatClient(String name, ChatServerIF chatServer) throws RemoteException {
this.name = name;
this.chatServer = chatServer;
chatServer.registerChatClient(this);
}
public void retrieveMessage(String message) throws RemoteException {
// TODO Auto-generated method stub
System.out.println(message);
}
public void run() {
Scanner scanner = new Scanner(System.in);
String message;
while(true){
message = scanner.nextLine();
try {
chatServer.broadcastMessage(name + " : " + message);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ChatClientDriver
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import com.za.tutorial.rmi.server.ChatServerIF;
public class ChatClientDriver {
public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
String chatServerURL = "rmi://localhost/RMIChatServer";
ChatServerIF chatServer = (ChatServerIF) Naming.lookup(chatServerURL);
new Thread(new ChatClient(args[0],chatServer)).start();
}
}
ChatClientInterface
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatClientIF extends Remote {
void retrieveMessage(String message) throws RemoteException;
}
ChatServer
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import com.za.tutorial.rmi.client.ChatClientIF;
public class ChatServer extends UnicastRemoteObject implements ChatServerIF {
private ArrayList<ChatClientIF> chatClients;
protected ChatServer() throws RemoteException {
chatClients = new ArrayList<ChatClientIF>();
}
public synchronized void registerChatClient(ChatClientIF chatClient)
throws RemoteException {
this.chatClients.add(chatClient);
}
public synchronized void broadcastMessage(String message) throws RemoteException {
int i = 0;
while(i < chatClients.size()){
chatClients.get(i++).retrieveMessage(message);
}
}
}
ChatServerDriver
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
public class ChatServerDriver {
public static void main(String[] args) throws RemoteException, MalformedURLException {
Naming.rebind("RMIChatServer", new ChatServer());
}
}
ChatServerInterface
import java.rmi.Remote;
import java.rmi.RemoteException;
import com.za.tutorial.rmi.client.ChatClientIF;
public interface ChatServerIF extends Remote {
void registerChatClient(ChatClientIF chatClient) throws RemoteException;
void broadcastMessage(String message) throws RemoteException;
}
When I run it on Commando, first of all I run rmic ChatClient and ChatServer, then rmiregistry. Then i run chatServerDriver which works completely fine. after that, when I run chatClientDriver with a name, I get the following error, I dont understand why :/ Can I get any solution for this?
Thanks :)
Exception in thread "main" java.rmi.NotBoundException: RMIChatServer
at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:136)
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Unknown Source)
at com.za.tutorial.rmi.client.ChatClientDriver.main(ChatClientDriver.java:15)
It also looks like you have a different address in Rebind to what is being used by the client to connect.
Naming.rebind("//localhost/RMIChatServer", new ChatServer());
There's an example implementation on the following Wikipedia page which may be worth comparing against your code.
http://en.wikipedia.org/wiki/Java_remote_method_invocation
Note that using Java 1.5+ you don't need to use rmic anymore see Do we really need to create Stub in java RMI?
According to this: http://undertow.io/ it supports websockets. There is no documentation on how to do so, though. I just want a simple embedded undertow handling web sockets example.
I don't want to grab the whole jboss app server.
Take a look at undertow examples
chat:
https://github.com/undertow-io/undertow/tree/master/examples/src/main/java/io/undertow/examples/chat
and websockets example
https://github.com/undertow-io/undertow/tree/master/examples/src/main/java/io/undertow/examples/websockets
this will help you.
I'm came up with this class. However, I am not an JBoss expert. I'm especially uncertain about the xnio stuff.
import io.undertow.Undertow;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.jboss.logging.Logger;
import org.xnio.OptionMap;
import org.xnio.Xnio;
import org.xnio.XnioWorker;
import javax.servlet.ServletException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import static io.undertow.servlet.Servlets.defaultContainer;
import static io.undertow.servlet.Servlets.deployment;
import static io.undertow.websockets.jsr.WebSocketDeploymentInfo.ATTRIBUTE_NAME;
public class WebsocketServer {
private static final Logger LOGGER = Logger.getLogger(WebsocketServer.class);
#ServerEndpoint("/")
public static class SocketProxy {
#OnOpen
public void onOpen() {
LOGGER.info("onOpen");
}
#OnClose
public void onClose() {
LOGGER.info("onClose");
}
#OnMessage
public void onMessage(String message) {
LOGGER.info("onMessage:" + message);
}
}
public static void main(String[] args) throws ServletException, IOException {
final Xnio xnio = Xnio.getInstance("nio", Undertow.class.getClassLoader());
final XnioWorker xnioWorker = xnio.createWorker(OptionMap.builder().getMap());
final WebSocketDeploymentInfo webSockets = new WebSocketDeploymentInfo()
.addEndpoint(SocketProxy.class)
.setWorker(xnioWorker);
final DeploymentManager deployment = defaultContainer()
.addDeployment(deployment()
.setClassLoader(WebsocketServer.class.getClassLoader())
.setContextPath("/")
.setDeploymentName("embedded-websockets")
.addServletContextAttribute(ATTRIBUTE_NAME, webSockets));
deployment.deploy();
Undertow.builder().
addListener(8080, "localhost")
.setHandler(deployment.start())
.build()
.start();
}
}