SVG-Grafik mit Javascript: Client/Host-Netzwerk möglich?

mtun

Mitglied
Hi,
ich habe gerade Spaß an SVG-Grafiken. Da kann ja Javascript nicht fehlen.
Nun stellt sich mir dir frage, ob ich wie zB in C++ mit Javascript auch Daten an eine IP an einen bestimmten Port senden und empfangen kann. Im Internet konnte ich bisher nix richtiges finden, mir fehlen wohl die Schlagwörter oder es geht nicht.

Hier ein Beispiel
Code:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
    version="1.1" baseProfile="full"      
    id="idsvg"
    onload="init()"
    viewBox="0 0 100 100"
    >


<defs>

<script type="application/ecmascript">
var svgns = "http://www.w3.org/2000/svg";

var hostIP = "127.0.0.1";
var myIP = "127.0.0.1";

function init(evt){
	document.documentElement.addEventListener("keydown", key_down_func, false);
}


function key_down_func (event)
{
	event.preventDefault();
	newText(event.keyCode);
}


function newText(text){

	var textAr = document.createElementNS(svgns, "textArea");


	textAr.setAttribute("x",Math.random()*95);
	textAr.setAttribute("y",Math.random()*95);

	textAr.textContent= String.fromCharCode(text);
	textAr.setAttributeNS(null, "font-size","5")
	textAr.setAttributeNS(null, "fill","grey")
	document.documentElement.appendChild(textAr);

	sendText(text);
	
}


function sendText(text){
	//send text to host


}

function receiveText(){
	//receive text from host
	//newText(receivedText)

	//as host: sendText to all clinets after receiving new text

}

</script> 

</defs>

</svg>
Die Datei soll eine Person als Host und mehrere als Client starten.
Sobald ein Client eine Eingabe macht, soll diese an den Host geschickt werden (mit bestimmer IP und port).
Dieser wiederum sendet es an alle anderen bekannten Clients.
Für den Anfang reicht ein Host und ein Client.
Ich möchte einfach nur Daten im Internet austauschen.

Reicht da Javascript oder benötigt es mehr?

(Datei im Anhang, muss noch in *.svg umbenannt werden, geht in Opera; in IE und Chrome nicht)
 

Anhänge

  • network.txt
    1,4 KB · Aufrufe: 17
Zuletzt bearbeitet:
Hi

Sockets in JS waren bis vor nicht all zu langer Zeit nicht möglich.
Inzwischen kann man sich die HTML5 Websockets anschauen.
Es gibt allerdings zurzeit noch einen nicht einfach vernachlässigbaren Anteil an Browsern,
die damit nicht umgehen können.
 
War vorher keine Art der Kommunikation möglich?

Naja, Port hin oder her, er ist legitimer Bestandteil einer URL, du kannst somit zumindest eine Anfrage dahin schicken(z.B. über ein Formular)

Problematisch wirds mit der Antwort, die zu erhalten ist idR. aus Sicherheitsgründen nicht möglich (höchstens per JSONP )
 
Hi,
danke für die Antwort.
Du hast Recht. Eine Anfrage geht mit:
(aus Links oben, sollte in Chrome und Opera mit Configänderung gehen)
(nicht funktionsfähig getestet (keinen Server installiert), zeigt nur an ob es überhaupt gehen kann und dass Socket wieder geschlossen wurde)
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
    version="1.1" baseProfile="full"      
    id="idsvg"
    onload="init()"
    viewBox="0 0 100 100"
    >
<defs>
<script type="application/ecmascript">

var ws = new WebSocket("ws://localhost:80");

ws.onopen = function(e) {
	// the connection is now established
	// let's send a simple message
	alert("open")	
	this.send('{"username": "Bruce", "message": "Hello!"}');
}

ws.onmessage = function(e) {
	// got a message from the server
	alert("resive")	
	var msg = JSON.parse(e.data);
	alert(msg.username +": "+msg.message);
}
ws.onclose = function(e) {
	alert("WebSocket closed");
}

ws.onerror = function(e) {
	alert("error");
}

function init(evt){
	if ('WebSocket' in window) {
		alert("geht")
	} else {
		alert("geht nicht")
	}
}
</script> 
</defs>
</svg>
Das Problem ist nur man muss beim Host einen Server installiert haben muss. zB http://code.google.com/p/pywebsocket/
Sowas wollte ich nicht. In C++ brauch man auch nur 10 Zeilen zu schreiben...

JSONP könnte helfen, nur noch nichts richtiges gefunden.
Jemand eine Idee?

EDIT: So wie ich das in Erfahrung bringen konnte ist JSONP, nur ein Datenaustauschformat und kein port listener. Oder? Dann muss ich wohl echt noch einen Server am laufen haben :(. Gibts da keine Möglichkeit einen solchen als Internetseite zu machen?

EDIT 2: Ich habe mal versucht so ein Server zu machen. Aber das scheint nicht so einfach. Die Websockets benötigen einen Handshake zu beginn der Kommunikation, der natürlich je nach Version und somit je nach Browser anders ist...
Mit dem Code von http://www.dreamincode.net/forums/topic/247892-websocket-server-handshake-problem/ geht zumindest Chrome (zeigt an, dass verbunden, weitere Kommunikation hat noch nicht geklappt). In Opera (für welches ich es brauche) ist jedoch ein anderer Handshake als der im Link verwendete (siehe http://www.htmlgoodies.com/html5/tutorials/making-html5-websockets-work.html). Der will aber nicht funktionieren. Sehr ihr einen Fehler?:
Code:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package network;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.Properties;

public class Socke {

    public Socke() {
        try {
            System.out.println("started");
            ServerSocket server = new ServerSocket(8080);
            while (true) {
                Socket client = server.accept();
                System.out.println("accept");
                InputStream in = client.getInputStream();
                OutputStream out = client.getOutputStream();
                String s;

                s = readLine(in); // first line, ignore it for now
                Properties props = new Properties();
                while ((s = readLine(in)) != null && !s.equals("")) {
                     String[] q = s.split(": ");
                    //props.put(q[0], q[1].toLowerCase());
                    props.put(q[0], q[1]);
                }
                int version = Integer.valueOf((String)props.get("Sec-WebSocket-Version"));
                
                if (props.get("Upgrade").equals("websocket") && version>=8) { // check if is websocket >=8
       
                    String key = (String) props.get("Sec-WebSocket-Key");
                    String r = key + "" + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // append "magic" key to it

                    MessageDigest md = MessageDigest.getInstance("SHA-1");
                    md.update(r.getBytes("iso-8859-1"), 0, r.length());
                    byte[] sha1hash = md.digest();

                    String returnBase = base64(sha1hash);

                    String ret = "HTTP/1.1 101 Switching Protocols\r\n";
                    ret += "Upgrade: websocket\r\n";
                    ret += "Connection: Upgrade\r\n";
                    ret += "Sec-WebSocket-Accept: " + returnBase + "\r\n";
                    ret += "\r\n";
                    out.write(ret.getBytes());
                    out.flush();


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

    private String base64(byte[] input) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> c = Class.forName("sun.misc.BASE64Encoder");
        java.lang.reflect.Method m = c.getMethod("encode", new Class<?>[]{byte[].class});
        String s = (String) m.invoke(c.newInstance(), input);
        return s;
    }

    private String readLine(InputStream in) {
        try {
            String line = "";
            int pread;
            int read = 0;
            while (true) {
                pread = read;
                read = in.read();
                if (read != 13 && read != 10) {
                    line += (char) read;
                }
                if (pread == 13 && read == 10) {
                    break;
                }
            }
            return line;
        } catch (IOException ex) {
        }
        return null;
    }

    public static void main(String... args) {
        new Socke();
    }
}
EDIT 3: Mit der neuen version 12.5 von Opera gehts jetzt auch (codeupdate). Jetzt müsst ich nur noch einen Nachricht senden/empfangen können.

EDIT4:
Beim empfangen von nachrichten vom Client bekomme ich bei zb.: " " 129.129.171.231.152.021.139 oder
129.129.127.099.091.126.095
ersten 2 Zahlen sind immer gleich. Die restlichen veränderns sich aber immer (beim gleichen Wort). Die erste Zahl is auch bei unterschiedlichen Wörtern gleich. Die Zweite gibt die Länge an (-128) dazu kommen noch 4 weitere Zahlen. Mehr konnt ich noch nicht rausfinden. Hab ihr eine Ahnung wie man das entschlüsselt?


Code:
                    NumberFormat form = new DecimalFormat("000");
                    int leng =0;
                    while (true) {
                        int i = in.read();
                        leng++;
                        System.out.print(form.format(i)+".");
                        if (in.available() == 0) {
                            break;
                        }                        
                    }
                    System.out.println("="+leng);
EDIT5: Habs!: http://tools.ietf.org/html/rfc6455#page-32. Also empfangen geht dann schon mal

EDIT6:
senden geht auch!
Code:
  String  test = "test";
  out.write(0x81);                    
  out.write(test.length()); 
  out.write(test.getBytes());
 
Zuletzt bearbeitet:
Zurück