Java Serveranwendung

Nord-Süd-Richtung

Erfahrenes Mitglied
Hi

ich weiß nicht ob ich hier richtig bin, aber es erschien mir am warscheinlichsten. Ich möchte mit Java eine Serveranwendung schreiben (ich habe gehört dass das möglich ist.) Ich stelle mir das ungefähr so vor:

Beispiel: Einfacher Chat
Code:
                    Nachricht          
[Client] ---------------------> [Server Anwendung]

          Liest alle eingeloggten Nutzer aus
[Server Anwendung] ----------------> [PHP-Script]
                    Schickt die neue Nachricht an alle Clienten
[Server Anwendung] ----------------------->[Client 1][Client 2][Client 3]

Dazu meine Fragen:
1. Ist das mit Java realisierbar?
2. Was müsste ich mir dazu anschauen?
3. (Wie) lässt sich die Anwendung dauerhaft laufen lassen auf dem Server?
 
Hallo,

ich verstehe nicht so ganz, was bei dir jetzt der Unterschied zwischen dem PHP-Script und der Serveranwendung ist.
Du kannst PHP mit Java ersetzen und die komplette Serverseite mit Java schreiben.
Du solltest dir mal Servlets und JSP anschauen.
Dazu gibt es auch noch einige Frameworks für die Client-Seite. Bspw GWT, JSF

Gruß

Sascha
 
Hi,

ich habe mich vielleicht etwas missverständlich ausgedrückt.
Ich habe mal ein Schaubild gemalt :)
Es haben sich 2 Clienten beim Server (bzw beim JavaProgramm) angemeldet. Wenn nun ein Client eine Nachricht schreibt, wird diese an das Server/Java-programm geschickt. Das wertet die Nachricht aus, und schickt dann die Antwort an alle angemeldeten Clienten. Der Unterschied zu einem PHP-Programm liegt darin, dass das PHP Script statisch ist, also um zu sehen, ob ich eine neue Nachricht bekommen hab, die Seite aktualisieren muss. Eine Alternative wäre AJAX, allerdings wird das alles sehr Performantslastig (irgendwann) und wenn man als einziger client angemeldet ist, mehr als verschwendete Resourcen.
 

Anhänge

  • java.bmp
    12,8 KB · Aufrufe: 24
Ich muss nochmal fragen, soll die Java-Anwendung der Server sein, der angesprochen wird?
Wie gesagt, alles was serverseitig ist, kann mit Java realisiert werden.

Soll der Client ein Webfrontend sein?
Sollen alle Clients benachrichtigt werden, sobald ein andere Client eine Nachricht geschickt hat, oder erst wenn sie die nächste Anfrage stellen?

Falls sie automatisch benachrichtigt werden sollen, d.h. ohne eine Anfrage an den Server zu stellen. Dann funktioniert das gar nicht mit Web-Frontend, weil der Server nur was zum Client schicken kann, sobald an ihn eine Anfrage gestellt wird.
Das funktioniert deshalb mit keine Programmiersprache.

Eine andere Möglichkeit wäre, einen richtige Applikation einzusetzen.

Gruß

Sascha
 
Hi

also ich nehme nochmal das Beispiel mit dem Chat.
Angenommen ich habe die Java-anwendung die ich schreiben möchte schon fertig. Diese liegt jetzt auf dem Server. Person A meldet sich jetzt entweder über ein Java-Programm oder ein Applet an, Username/Password und wird dann in eine Datenbanktabelle eingetragen. Person B meldet sich auch an, und kommt in die gleiche Tabelle. Person A sieht jetzt dass Person B online ist, und schreibt eine Nachricht in den generellen Chat. Sprich, es wird ein Text in ein Textfeld eingegeben, und auf Senden gedrückt. Jetzt müsste die Javaanwendung auf dem Server ins spiel kommen. Beim Senden wir der Javaanwendung "gesagt" dass sie die mitgesendete Nachricht an alle angemeldeten Clienten schicken soll.
Diese Javaanwendung muss dementsprechend die ganze Zeit verfügbar sein.
 
Also für das was du vor hast, reicht eine normale Java Socketverbindung.
Das heißt du könntest dir die Socket-Programmierung unter Java anschauen.

Eine weitere Möglichkeit wäre noch JMS.

Gruß

Sascha
 
Hey Sascha,

vielen Dank für deine Geduld und deine Auskunft/Hilfe.
Ich habe mir jetzt mal folgenden Code gebastelt, nachdem ich hier gelesen habe: http://www.peuss.com/java/Sockets.php. Zunächst hat auch alles geklappt, bis ich mir eine GUI gebaut habe. Ich erhalte leider weder eine Fehlermeldung, noch eine Ausgabe. Kannst du mir noch einmal helfen? :)
Java:
/* Server */
import java.io.*;
import java.net.*;
public class Server {
	int port = 1066;
	ServerSocket server = new ServerSocket(port);
	char c;
	int i;
	Server() throws IOException{
		while(true){
			Socket client = server.accept();
			InputStream input = client.getInputStream();
			OutputStream output = client.getOutputStream();			
			while(true){
				i = input.read();
				if( i == -1)
					break;
				c = (char)i;
				output.write(c);
			}
			output.flush();
			input.close();
			output.close();
		}
	}
	public static void main(String[] args) {
		try{
			new Server();
		}
		catch(IOException e){
			System.out.print(e);
		}
	}

}
Java:
/* Client */
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
public class ChatClient extends Frame implements ActionListener{
	private int port;
	private String host;
	private int i;	
	private Button send;
	private TextField chat_msg;
	private TextArea chat;
	static final long serialVersionUID = 1;
	public ChatClient() {
		this.port = 1066;
		this.host = "localhost";
		/* Layout */
		this.setLayout(new FlowLayout());
		
		this.chat_msg = new TextField(30);
		this.add(this.chat_msg);
		
		this.chat = new TextArea("",10,20,TextArea.SCROLLBARS_VERTICAL_ONLY);
		this.chat.setEditable(false);
		this.add(this.chat);
		
		this.send = new Button("send");
		this.send.addActionListener(this);
		add(this.send);
		
		this.pack();
		
		this.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent evt){
				System.exit(0);
			}
			
		});
		this.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent evt){
				int key = evt.getKeyCode();
				if( key == KeyEvent.VK_ESCAPE){
					setVisible(false);
					dispose();
				}
			}
		});
	}	
	public static void main(String[] args) {      
      /* Window */
      ChatClient window = new ChatClient();
      window.setBackground(Color.gray);
      window.setTitle("Chat Client");
      window.setSize(250,400);
      window.setVisible(true);
      window.setResizable(false);
      
	}
	public void actionPerformed(ActionEvent evt){
		if( evt.getSource() == this.send ){	
			String msg = this.chat_msg.getText();
			this.chat_msg.setText("");
			ChatClient client = new ChatClient();
		    try{
		    	client.send_msg(msg);
		     }
		     catch(IOException e){
		    	 this.chat_msg.setText(e.toString());
		     }
		}
	}
	private void send_msg(String msg) throws IOException{		
		Socket server = new Socket(this.host,this.port);
		InputStream input = server.getInputStream();
		OutputStream output = server.getOutputStream();
		for( int k = 0; k < msg.length(); k++){
			output.write(msg.charAt(k));
		}
		output.flush();	
		String buffer = "";
		while(true){
			i = input.read();
			if( i == -1)
				break;			
			buffer += (char)i;
		}
		this.chat.append(buffer+"\r\n");
		server.close();
		input.close();
		output.close();			
	}

}
 
Hab dein Programm mal schnell etwas umgestellt. Es ist nicht perfekt, aber es zeigt den Ansatz.

Java:
package tutorials;

import java.io.*;
import java.net.*;
import java.util.List;
import java.util.Vector;

public class Server {
	int port = 1066;
	ServerSocket server = new ServerSocket(port);
	char c;
	int i;
	private List<Socket> newClients = new Vector<Socket>();
	private List<Socket> runningClients = new Vector<Socket>();

	Server() throws IOException {
		scanningForClients();
		readingFromClients();
	}

	private void readingFromClients() {
		new Thread() {

			@Override
			public void run() {

				while (true) {
					synchronized (newClients) {
						if (newClients.size() > 0) {
							for (int i = 0, size = newClients.size(); i < size; i++) {
								final Socket client = newClients.get(i);

								runningClients.add(client);
								startReadingFromClient(client);
							}
							newClients.clear();
						}
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}.start();
	}

	private void startReadingFromClient(final Socket client) {
		new Thread() {
			public void run() {
				try {
					InputStream input = client.getInputStream();
					int i;
					while (true) {

						i = input.read();
						if (i == -1)
							break;
						c = (char) i;
						writeToClients(c);
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
	}

	private void writeToClients(final char c) {

		synchronized (runningClients) {

			try {
				for (Socket client : runningClients) {
					if (!client.isClosed()) {
						OutputStream output = client.getOutputStream();
						output.write(c);
						output.flush();
					} else {
						runningClients.remove(client);
					}
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	private void scanningForClients() {
		new Thread() {

			@Override
			public void run() {

				while (true) {
					Socket client = null;
					try {
						client = server.accept();
					} catch (IOException e) {
						e.printStackTrace();
					}
					newClients.add(client);
				}
			}

		}.start();
	}

	public static void main(String[] args) {
		try {
			new Server();
		} catch (IOException e) {
			System.out.print(e);
		}
	}
}

Java:
package tutorials;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ChatClient extends JFrame implements ActionListener {
	private int port;
	private String host;
	private JButton send;
	private JTextField chat_msg;
	private JTextArea chat;
	static final long serialVersionUID = 1;
	private PrintWriter writer;
	private Socket client = null;

	public ChatClient() throws IOException {
		this.port = 1066;
		this.host = "localhost"; /* Layout */
		JPanel contentPane = (JPanel) getContentPane();
		this.chat_msg = new JTextField(30);
		contentPane.add(this.chat_msg, BorderLayout.NORTH);
		this.chat = new JTextArea();
		this.chat.setEditable(false);
		contentPane.add(new JScrollPane(chat), BorderLayout.CENTER);
		this.send = new JButton("send");
		this.send.addActionListener(this);
		contentPane.add(this.send, BorderLayout.SOUTH);
		this.pack();

		openConnection();
		startReadingFormSocket();

		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent evt) {

				try {
					client.close();
					System.exit(0);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

	}

	public static void main(String[] args) throws IOException { /* Window */
		ChatClient window = new ChatClient();
		window.setBackground(Color.gray);
		window.setTitle("Chat Client");
		window.setSize(250, 400);
		window.setVisible(true);
		window.setResizable(true);
	}

	public void actionPerformed(ActionEvent evt) {
		if (evt.getSource() == this.send) {
			String msg = this.chat_msg.getText();
			this.chat_msg.setText("");

			try {
				send_msg(msg);
			} catch (IOException e) {
				this.chat_msg.setText(e.toString());
			}
		}
	}

	private void send_msg(String msg) throws IOException {

		writer.write(msg);
		writer.flush();

	}

	private void openConnection() {
		try {
			client = new Socket(this.host, this.port);
			writer = new PrintWriter(client.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void startReadingFormSocket() {

		new Thread() {
			public void run() {
				try {

					int i;
					final InputStream input = client.getInputStream();
					while (!client.isClosed()) {
						try {
							while ((i = input.read()) != -1) {
								chat.append((char) i + "");
							}

						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
}


Gruß

Sascha
 
Hey

super Dank, das funktioniert (natürlich) soweit :) Ich habe jetzt noch einen Chatusernamen und einen Zeilenumbruch hinzugefügt. Solang ich das ganze lokal teste, funktioniert es auch. Ich starte zuerst in eclipse Server.class und danach den ChatClient, und kann mich mit mir selbst unterhalten :p
Nur habe ich die Server.class jetzt auf den Webserver heraufgeladen, und den host von localhost zu der ip adresse umbenannt. Allerdings erhalte ich dann einen Connection timeout. Wenn ich es mit ip/Server.class versuche, erhalte ich eine UnkownHostException. Ich vermute mal, dass ich die Server.class irgendwie auf dem Server zum laufenkriegen muss, nur wie?
 
Hi

ich habe nochmal ein bisschen weiter rumgeschaut, aber immer noch keine Lösung gefunden. Ist sowas denn prinzipiell überhaupt möglich (womit wir bei meiner Ausgangsfrage wären). IRC ist doch auch Javabasierend (zumindest das Applet), da funktioniert das doch auch, oder nicht?
 
Zurück