Problem mit der verwirklichung einer Readmethode in einer Chatapplikation

Shams

Aktives Mitglied
Ich habe ein Problem etwas komplizierterer Natur.

Ich schreibe gerade an einer Chatapplikation, wobei ich vorhabe, die Chat-UI dem User als Vaadin-Servlet zur Verfügung zu stellen.

In dem Moment, da die enter-Methode durchlaufen wird (die muss in jedem VaadinServlet implementiert sein), passiert folgendes:

Java:
public void enter(ViewChangeEvent event) {
	
//dispatch
write("1"+":"+(String)UI.getCurrent().getSession().getAttribute("currentUser")+"\n");
		
//reads everything incoming from the dipatcher
//HOW?????? -> Das ist mein Problem, siehe Erklärung hier im Threadpost.
 
}


Es wird eine write-Methode aufgerufen, die durch einen Outputstream an einen Serversocket eine Mitteilung schreibt, eine „1+currentUser“. Eins bedeutet dabei, dass der User online ist. Hier die Serverklasse, wie diese funktioniert, bitte den Kommentaren entnehmen.

Java:
package dispatching;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.io.*;

import com.vaadin.ui.Notification;

public class MainServer extends Thread
{
   private ServerSocket serverSocket;
   private HashMap<String,Socket> dispatch = new HashMap<String,Socket>(); 
   private BufferedReader br = null; 
   private BufferedWriter bw = null;
   
   public MainServer(int port) throws IOException
   {
      serverSocket = new ServerSocket(port);
      //serverSocket.setSoTimeout(10000);//Kann am Ende weg.
   }
 
   public void run()
   {
	  	   
      while(true)
      {
         try
         {
            
            Socket server = serverSocket.accept();//Bis hier is klar, ne?
            
           try{
           	   
              br = new BufferedReader(new InputStreamReader(new DataInputStream(server.getInputStream())));

             String line = br.readLine();
             
	  

if(line.split(":")[0].equals("1")){//Also wenn der Buddy on == 1 ist...

	
	if(line.split(":").length==3){//Also wenn Botschfaten geschrieben warden, dann ist line.split(":")[1] immer der Adressat (addressee) und line.split(":")[2] ist immer die Message.  
		 
		dodispatch(line.split(":")[1],line.split(":")[2]);		
	
	}
	
}
           
}catch(IOException e){e.printStackTrace();}
      
          //server.close(); // ???
         }catch(SocketTimeoutException s)
         {
            System.out.println("Socket timed out!");
            break;
         }catch(IOException e)
         {
            e.printStackTrace();
            break;
         }      
      }
      
   }
  
   private void dodispatch(String addressee, String message){

	   //Hier will ich eine HashMap aus Benutzern, die Online sind jeweils mit deren akzeptierten Sockets als Values durchlaufen, um die an den jeweiligen Adressaten adressierte Nachricht dem richtigen Mann / Frau zuzustellen, aber erstmal habe ich es so geschrieben, dass alles an den Testuser zurückgeht, wie ein Echo, halt auch über nen Stream, sieht so zwar schlecht aus, dürfte aber klar sein, was gemeint ist.  

	   for(String str : dispatch.keySet()){
		 
	      //if(str.equals(addressee)){ 
	      /*Vorerst:*/if(str.equals("testuser")){	 
	    	  try{
	    		
	    	  /*Vorerst:*/bw = new BufferedWriter(new OutputStreamWriter(new DataOutputStream(dispatch.get("testuser").getOutputStream())));//This does not go to testuser3, but is echoed back t the testuser.    		  
	    	  //bw = new BufferedWriter(new OutputStreamWriter(new DataOutputStream(dispatch.get(addressee).getOutputStream()))); 
	    	  bw.write(message+"\n");//If the message contained an \n, it would a spurious deed to add one more, but it doesn't.
	    	  bw.flush();
	    	  
	    	  }catch(IOException e){ e.printStackTrace(); }
	      }
		   
	   }
	}



//Das ist die Main des Servers.
public static void main(String [] args)
   {
    
      try
      {
         Thread t = new MainServer(8754);
         t.start();
      }catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}


Sobald sich der User angemeldet habe, habe ich im Clienten eine eventbasierte Art und Weise entwickelt, wie ich dann aus dem Chatfenster Botschaften abgreife, und wenn der User halt ne Nachricht senden will, also auf senden drückt, wird halt wieder die write-Methode aufgerufen.

--> Jetzt habe ich ein riesen Problem: Ich kann im Clientlistener keinen InputstreamReader in einer while(true) Schleife laufen lassen, weil sonst alles blkiert - was soll ich tun? Ich kann auch gerne den gesamten Quellcode posten, wenn das so erwünscht ist.
 
Zuletzt bearbeitet von einem Moderator:

Shams

Aktives Mitglied
Update:


Ich habe die ganze Sache nun versucht, einmal vermittels der Anwendung des

Code:
com.google.gwt.thirdparty.guava.common.eventbus.EventBus


…die Readermethode des Clientreaders aufzurufen. Bevor ich das aber tue, wollte ich einmal ausprobieren, ob das überhaupt geht.

Ich habe also meine UI-Klasse, und in dieser habe ich eine Subscribermethode, welche den Inputstream des Clientsockets liest, und mir per Notification anzeigt, dass sie das tut.


Java:
@Subscribe
@AllowConcurrentEvents
private void readIncomingMessages(EventBroadcastEvent e){
	Notification.show("Ein Event kommt geflogen.");
BufferedReader bufferedReader = null;
try{
	if(client != null){
bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));	  
	char[] buffer = new char[200];
	  new String(buffer,0,bufferedReader.read(buffer, 0, 200));
	}
   }catch(IOException eOfBroadCast){ eOfBroadCast.printStackTrace(); }
}


Der client-Socket ist der UI-Klasse eigen. Den EventBus lasse ich mir aus einem Singleton ausgeben (siehe Code weiter unten). Beim Betreten des VaadinUIs wird der Eventbus registriert.

Java:
@Override
public void enter(ViewChangeEvent event) {
	
 . . .  


    EventBusSingleton.getInstance().register(this);

		 
 . . . 

}

Und wie werfe ich derzeit das Event wie folgt:



Dies geschieht wie folgt (in meiner Serverklasse):


Java:
EventBusSingleton.getInstance().post(new EventBroadcastEvent());



Hier zu guter Letzt das Singleton:

Java:
import com.google.gwt.thirdparty.guava.common.eventbus.EventBus;

public class EventBusSingleton {
	
	
	private static EventBus eventBus = null;
	 
    /**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse
     * aufgerufen werden kann
     */
    private EventBusSingleton() {}
 
    /**
     * Statische Methode, liefert die einzige Instanz dieser
     * Klasse zurück
     */
    public static EventBus getInstance() {
        if (eventBus == null) {
        	eventBus = new EventBus();
        }
        return eventBus;
    }
	
	
}
 
Zuletzt bearbeitet von einem Moderator:

Shams

Aktives Mitglied
… danke für den Hinweis.


Um die Sache mal ein bisschen greifbarer zu machen, habe ich aus meinem Ursprünglichen Code das Problem herausgezogen und eine Minianwendung geschrieben, die mein derzeitiges Problem simuliert. Es ist wohlgemerkt auch eine Vaadingeschichte.

Meine Minianwendung besteht aus den drei Packages com.example.vaadin7scratch, dispatching sowie sockets.

Die Idee ist diejenige, dass es einen Sever gibt, der just in dem Moment, da er eine Nachricht bekommt, über einen Eventbus ein Event fetzen lässt, welches dann durch eine Subscribermethode aufgefangen werden soll, und dieses Event soll dann in einer Notification angezeigt werden.


Kern der Minianwendung, von wo aus auch die Messages geschrieben werden, ist die GUI in com.example.vaadin7scratch:

Java:
package com.example.vaadin7scratch;

import java.io.*;
import java.net.*;

import javax.servlet.annotation.WebServlet;

import com.google.gwt.thirdparty.guava.common.eventbus.AllowConcurrentEvents;
import com.google.gwt.thirdparty.guava.common.eventbus.Subscribe;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import dispatching.EventBroadcastEvent;
import dispatching.EventBusSingleton;

@SuppressWarnings("serial")
@Theme("vaadin7scratch")
public class Vaadin7scratchUI extends UI {
	
	Socket client = null;
	DataOutputStream out = null;
	BufferedWriter bw = null;

	@WebServlet(value = "/*", asyncSupported = true)
	@VaadinServletConfiguration(productionMode = false, ui = Vaadin7scratchUI.class)
	public static class Servlet extends VaadinServlet {
	}
	
	
	@Subscribe
	@AllowConcurrentEvents
	private void readIncomingMessages(EventBroadcastEvent e){
		Notification.show("Nachricht von "+e.getName());//Erst soller mir mal das ausgeben, sonst werde ich nichtfroh :\ getName() soll mir die neues Messages ausgeben.
	
//		BufferedReader bufferedReader = null;
//	try{
//		if(client != null){
//	bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));	  
//		char[] buffer = new char[200];
//		  new String(buffer,0,bufferedReader.read(buffer, 0, 200)); //Das ist die Nachricht, die muessen wir noch mit einem Singnal ins richtige Chatfenster oder nach unreadMessages bugsieren.
//		}                                                           //Und wenn es nicht moeglich ist, dies in ein Textfenster hineinzusetzen, dann muss an der richtigen Stelle ein Unread-Message-Singal ausgegeben werden.
//	   }catch(IOException eOfBroadCast){ eOfBroadCast.printStackTrace(); }

	}	
	

	@Override
	protected void init(VaadinRequest request) {
		final VerticalLayout layout = new VerticalLayout();
		layout.setMargin(true);
		setContent(layout);

		 EventBusSingleton.getInstance().register(this);
		 write("This is message is written as soon as the user beholds the newly created UI."+"\n");
		
		
		Button button = new Button("Click Me");
		button.addClickListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				
				write("New Message");
				layout.addComponent(new Label("Thank you for clicking and Your new message"));
			
			}
		});
		layout.addComponent(button);
	}

	private void write(String towrite){

		//Sobald der User chatfaehig wird (durch Betreten dieser View), wird automatisch ein Stream geoeffnet.
		try {
			client = new Socket("127.0.0.1", 8754);
			out = new DataOutputStream(client.getOutputStream());
			bw = new BufferedWriter(new OutputStreamWriter(out));	
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
		
		try {

		bw.write(towrite);
		bw.flush();
		//bw.close();

		}catch (IOException e) {

		e.printStackTrace();
		
		   }
		}

}

Dann gibt es in dem package sockets noch den server:

Java:
package sockets;

import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.io.*;

import com.google.gwt.thirdparty.guava.common.eventbus.EventBus;
import com.vaadin.ui.Notification;

import dispatching.EventBroadcastEvent;
import dispatching.EventBusSingleton;

public class Server extends Thread
{
   private ServerSocket serverSocket;
   private HashMap<String,Socket> dispatch = new HashMap<String,Socket>(); 
   private BufferedReader br = null; 
   private BufferedWriter bw = null;
   
   public Server(int port) throws IOException
   {
      serverSocket = new ServerSocket(port);
      //serverSocket.setSoTimeout(10000);//Kann am Ende weg.
   }
 
   public void run()
   {
	  	   
      while(true)
      {
         try
         {
            
            Socket server = serverSocket.accept();
            
           try{
           	   
              br = new BufferedReader(new InputStreamReader(new DataInputStream(server.getInputStream())));

             String message = br.readLine();//Hier mit dieser Methode ist etwas nicht in Ordnung.
             


EventBusSingleton.getInstance().post(new EventBroadcastEvent(message));


}catch(IOException e){e.printStackTrace();}
      
      
         }catch(SocketTimeoutException s)
         {
            System.out.println("Socket timed out!");
            break;
         }catch(IOException e)
         {
            e.printStackTrace();
            break;
         }      
      }
      
   }


public static void main(String [] args)
   {
    
      try
      {
         Thread t = new Server(8754);
         t.start();
      }catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}

Zu guter Letzt habe ich noch in dem package dispatching alles, was etwas mit Events zu tn hat, d.h. eine Eventklasse, deren Konstruktor ich überladen habe und eben meinen EventBus, den ich immer als Singleton ausgebe – hier die beiden:


Java:
package dispatching;

import com.google.web.bindery.event.shared.Event;

public class EventBroadcastEvent extends Event{

	String name;
	
	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public EventBroadcastEvent(String nam){
		super();
		name=nam;
	}
	
	
	@Override
	public Type getAssociatedType() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void dispatch(Object handler) {
		// TODO Auto-generated method stub
		
	}
	
}

Java:
package dispatching;

import com.google.gwt.thirdparty.guava.common.eventbus.EventBus;

public class EventBusSingleton {
	
	
	private static EventBus eventBus = null;
	 
    /**
     * Default-Konstruktor, der nicht außerhalb dieser Klasse
     * aufgerufen werden kann
     */
    private EventBusSingleton() {}
 
    /**
     * Statische Methode, liefert die einzige Instanz dieser
     * Klasse zurück
     */
    public static EventBus getInstance() {
        if (eventBus == null) {
        	eventBus = new EventBus();
        }
        return eventBus;
    }
	
	
}

Meine konkrete Frage ist eben, weshalb das nicht geht, er müsste das Event doch eigentlich einfangen, oder bin ich da ganz auf dem falschen Weg?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S AJAX/RestController Post Problem Web Tier 18
pkm Problem beim Import eines dynamischen Webprojekts als .zip Web Tier 2
O JSF Java Unsigned Applet PrivilegedActionException Problem Web Tier 2
F JSF preRenderView Problem Web Tier 0
J Funktion für AJAX - Problem mit Return Web Tier 14
S Problem mit Checkboxen im Servlet erkennen Web Tier 3
N JSF JSF Selected Item & GesBetrag Problem Web Tier 1
F JSF Problem mit Primefaces Web Tier 7
F JSF Problem mit Primefaces Web Tier 4
F JSP Problem mit Property Web Tier 0
D Java EE Servlet login Problem Web Tier 1
L java.io.NotSerializableException für domain Objekte - Design Problem? Web Tier 12
T JSF Character Encoding Problem Web Tier 2
T JSF Problem mit JSF und Foreign Key Tabellen Web Tier 8
H JSF Problem mit Converter Web Tier 2
M Zeichensatz Problem? Web Tier 3
T JSF Problem wenn Session abgelaufen ist Web Tier 6
K JSF websphere application server 8 tomahawk problem Unable to find resource Web Tier 3
D JSF RichFaces Tree-Beispiel Problem Web Tier 2
J JSF Problem mit Bearbeiten von Datensätzen Web Tier 7
M JSF Problem mit CSS und Unterverzeichnissen Web Tier 2
M JSP Problem beim deployen auf Tomcat Web Tier 2
P Servlet getWidth(); - getHight(); Problem Web Tier 3
J JSP Problem bei Hibernate mit JSP Web Tier 2
M JSF mit Tobago Problem: ServletContextListener Web Tier 5
J Facelets javascript compiler problem Web Tier 3
T Tomcat mit Servlets Problem Web Tier 7
T Servlet Problem bei gwt rpc Web Tier 7
S Servlet Problem mit Tomcat Web Tier 3
J JSF Kein Methodenaufruf mit Button möglich durch PhaseListener (redirect) Problem? Web Tier 2
P rich:panelMenuGroup --> expanded Parameter Problem Web Tier 3
F.S.WhiTeY Tmplating/CSS Problem bei JSF Web Tier 7
A ice:inputText Converter Problem Web Tier 2
B JSF Tomcat Windows Linux equals Problem Web Tier 3
R JSF JSF Composite Components: Problem mit Attributliste und Referenzierung Web Tier 2
M Problem mit Hibernate und GWT Web Tier 6
O JSP struts2 tag: Problem mit Dezimalzahlen Web Tier 2
P Struts Struts2 if tag Problem mit getText() Web Tier 3
B Java EE 6 Problem (EL) Web Tier 4
ruutaiokwu beanshell scope problem... Web Tier 7
P Problem mit HTML.Tag.OPTION Web Tier 3
N Problem mit Datei Streaming Web Tier 2
M Problem mit Verlinkung JSP Dynamische Tabelle Web Tier 7
S Architektur-Problem? 2 Servlets, ein Objekt Web Tier 4
F.S.WhiTeY JSF:org.apache.jasper.JasperException Problem Web Tier 2
H Richfaces - Taglib Problem gelb unterstrichen Ajax Output Web Tier 6
N Servlet: Problem mit getParameterValues Web Tier 4
7 Struts und Ajax. Problem mit Actions Web Tier 2
J GWT - RPC Problem Web Tier 6
F Problem mit JSF Anwendung Web Tier 9
I Logout - Problem => Bei Zurück Web Tier 2
I AJAX - Problem Web Tier 18
F Problem mit Struts Web Tier 2
I selectOneMenu - Problem Web Tier 6
H Firefox Background-Image Problem Web Tier 4
E GWT Server-Client Problem Web Tier 3
J Log4j problem Web Tier 7
F Problem mit der Methode request.getRemotePort() Web Tier 2
S GWT Problem Web Tier 4
M Problem mit Velocity Web Tier 2
S OSGi Bundle Problem - ClassNotFound Web Tier 4
J JSF Locales Problem Web Tier 3
J Problem mit Login Web Tier 4
MQue jsp- Problem Web Tier 4
P Problem der Parameterübergabe aus Iframe Web Tier 15
A Tomcat: beim Start des Servers einmalige Aktion aufrufen (Problem gelöst) Web Tier 2
R JSF <rich:datatable> problem Web Tier 4
S JSF Problem - Terminverwaltung - Ändern eines vorhandenen Termins Web Tier 2
S Filter Problem? Web Tier 6
E Problem mit t:saveState Web Tier 7
S Problem mit Anzeige zweier JSP's Web Tier 4
M Problem mit JSP und Bean Web Tier 2
F RichFaces, Problem mit PickList Web Tier 2
S Problem mit Servlet und Zugriff auf Orace XE Datenbank Web Tier 2
E Problem mit request.getParameter Web Tier 5
B getServletContext.getRealPath("/") Problem Web Tier 6
C Problem mit Hibernate und IceFaces Web Tier 2
S Problem mit Session - Übergabe von Kontext zu Kontext Web Tier 2
H problem bei Parameterübergabe mit beans Web Tier 3
U JSP form-Daten (ohne name-Attribut) an Servlet = Problem Web Tier 6
S jsf: übles problem mit <f:convertDateTime> Hilfe! Web Tier 2
A Selectbox Problem in JSP Web Tier 12
T Problem bei Session-Timeout Web Tier 3
S problem mit resultset Web Tier 6
U Problem bei Validierung mit Struts 2 Web Tier 1
A JSF-Ctrl h:inputText Problem mit Umlauten Web Tier 4
M In einer HTML Tabelle positionieren Web Tier 4
I Daten einer Datenbank in ein Formular einfügen Web Tier 3
N RequestDispatcher: include-Aufruf einer jsp scheitert nach mehreren forward-Aufrufen Web Tier 1
F JSF Popup mit einer Checkbox Auswahlliste Web Tier 1
S Rendern einer Komponente nach actionListener Web Tier 2
A Aufruf eines Servlets auf einer JSP Seite funktioniert nicht Web Tier 10
M JSF JSP, Facelets und einbinden einer js-Datei Web Tier 2
J JSF Initialisierung einer ApplicationScoped Bean Web Tier 2
J Anzeige einer Hierarchie Web Tier 5
M Exception beim Erstellen einer Query Web Tier 9
N JSF Architektur/Design einer JEE 6 + JSF 2.x Webanwendung mit Subdomänen Web Tier 4
J Performance einer Webanwendung Web Tier 2
V JSF Rendering abhängig von einer Auswahl Web Tier 8
P JSF Merkwürdiges Verhalten einer Bean Web Tier 11

Ähnliche Java Themen

Neue Themen


Oben