2014-11-21 10 views
5

Ho cercato di creare un client IRC per l'app per Windows Phone 8.1 e ho avuto la fortuna di trovare un tutorial davvero valido. Sfortunatamente il tutorial era per WP 7 e dal WP 8.1 MS lo ha cambiato in app di runtime, ovvero SocketAsyncEvents non è disponibile per me (anche se MSDN dice che supporta Windows Phone 8.1).Windows Phone 8.1 IRC

public void SendToServer(string message) 
{ 
    var asyncEvent = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(server, serverPort) }; 

    var buffer = Encoding.UTF8.GetBytes(message + Environment.NewLine); 
    asyncEvent.SetBuffer(buffer, 0, buffer.Length); 

    connection.SendAsync(asyncEvent); 
} 

Scavando in giro ho trovato che le prese sono stati spostati Windows.Networking.Sockets, ma ancora nessuno di essi contenevano SocketAsyncEvents.

Non riesco praticamente più ad andare oltre, qualcuno ha un'idea su come convertire la funzione in qualcosa che potrebbe funzionare con WP 8.1?

+0

Il progetto è Windows Phone 8.1 Runtime (app universale) o Windows 8.1 silverlight? – crea7or

+0

Ho trovato una soluzione, aggiornerò questo post non appena avrò finito di scrivere una lezione per questo :) grazie per esserti interessato. E sì, è durata :) – Jazerix

risposta

4

Ecco qui!

Dopo un sacco di ricerca questo è quello che ho trovato:

Prima di tutto abbiamo ottenuto un metodo connect.

private readonly StreamSocket _clientSocket; 
private bool _connected; 
private DataReader _dataReader; 
public string Hostname { 
    get; 
    set; 
} 
public int Port { 
    get; 
    set; 
} 
public Credentials Credentials; 
public readonly string Channel; 

public async Task <bool> Connect() { 
    if (_connected) return false; 
    var hostname = new HostName(Hostname); 
    await _clientSocket.ConnectAsync(hostname, Port.ToString()); 
    _connected = true; 
    _dataReader = new DataReader(_clientSocket.InputStream) { 
     InputStreamOptions = InputStreamOptions.Partial 
    }; 
    ReadData(); 
    return true; 

} 

Per leggere i dati che riceviamo attraverso la StreamSocket, creiamo un metodo ReadData() e renderlo ricorsiva quindi dovremo continuare ad ottenere i dati:

async private void ReadData() { 
    if (!_connected || _clientSocket == null) return; 
    uint s = await _dataReader.LoadAsync(2048); 
    string data = _dataReader.ReadString(s); 
    if (data.Contains("No ident response")) SendIdentity(); 
    if (Regex.IsMatch(data, "PING :[0-9]+\\r\\n")) ReplyPong(data); 
    ReadData(); 
} 

ora abbiamo due nuovi metodi , SendIdentity(); e ReplyPong(string message); di solito il server IRC sarà il ping voi, qui si deve rispondere con un pong, in questo modo:

private void ReplyPong(string message) { 
    var pingCode = Regex.Match(message, "[0-9]+"); 
    SendRawMessage("PONG :" + pingCode); 
} 

e abbiamo anche devono inviare la nostra identità quando il server è pronto per questo, in questo modo:

private void SendIdentity() { 
    if (Credentials.Nickname == string.Empty) Credentials.Nickname = Credentials.Username; 
    SendRawMessage("NICK " + Credentials.Nickname); 
    SendRawMessage("USER " + Credentials.Username + " " + Credentials.Username + " " + Credentials.Username + " :" + Credentials.Username); 
    if (Credentials.Password != String.Empty) SendRawMessage("PASS " + Credentials.Password); 
} 
public class Credentials { 
    public string Nickname { 
     get; 
     set; 
    } 
    public string Username { 
     get; 
     set; 
    } 
    public string Password { 
     get; 
     set; 
    } 

    public Credentials(string username, string password = "", string nickname = "") { 
     Username = username; 
     Password = password; 
     Nickname = nickname; 
    } 
} 

Finalmente abbiamo il nostro metodo di SendRawMessage();, che invia i dati al server.

async private void SendRawMessage(string message) { 
    var writer = new DataWriter(_clientSocket.OutputStream); 
    writer.WriteString(message + "\r\n"); 
    await writer.StoreAsync(); 
    await writer.FlushAsync(); 
    writer.DetachStream(); 
    if (!_closing) return; 
    _clientSocket.DisposeSafe(); 
    _connected = false; 
} 

quasi dimenticato la funzione di smaltire, che è possibile chiamare quando si vuole chiudere il flusso :)

public void Dispose() 
{ 
    SendRawMessage("QUIT :"); 
    _closing = true; 
} 

Questo invierà un ultimo messaggio che indica che ce ne andiamo, e dato che ora _closing è vero, lo stream verrà eliminato in seguito.