2014-11-21 14 views
5

Próbowałem zrobić klienta IRC dla mojej aplikacji Windows Phone 8.1 i miałem szczęście znaleźć naprawdę dobry tutorial. Niestety tutorial był dla WP 7 i od WP 8.1 MS zmienił go na aplikacje runtime, co oznacza, że ​​SocketAsyncEvents jest dla mnie niedostępna (mimo że MSDN twierdzi, że obsługuje 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); 
} 

Kopanie wokół znalazłem, że gniazda zostały przeniesione do Windows.Networking.Sockets, ale jeszcze żaden z nich nie zawierała SocketAsyncEvents.

Nie jestem już w stanie przejść dalej, czy ktoś ma pomysł, jak przekonwertować tę funkcję na coś, co będzie działać z WP 8.1?

+0

Twój projekt to Windows Phone 8.1 Runtime (aplikacja uniwersalna) lub Windows 8.1 silverlight? – crea7or

+0

Znalazłem rozwiązanie, będę aktualizować ten wpis, gdy tylko skończę pisać zajęcia dla niego :) dziękuję za zainteresowanie. I tak, to czas wykonywania :) – Jazerix

Odpowiedz

4

Oto idzie!

Po wielu badań jest to, co znalazłem:

Przede wszystkim mamy metodę 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; 

} 

Aby odczytać dane, które otrzymujemy za pośrednictwem StreamSocket tworzymy metodę ReadData() i sprawiają, że rekurencyjnych więc będziemy kontynuować, aby uzyskać dane:

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(); 
} 

Teraz mamy dwie nowe metody , SendIdentity(); i ReplyPong(string message); Zwykle serwer IRC ping, tutaj trzeba odpowiedzieć z pong, tak:

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

i my również trzeba wysłać naszą tożsamość, gdy serwer jest gotowy na to, jak w przykładzie:

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; 
    } 
} 

W końcu mamy SendRawMessage(); metodę, która wysyła dane do serwera.

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; 
} 

Prawie zapomniałem się wrzucać funkcji, które można nazwać, jeśli chcesz, aby zamknąć strumień :)

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

Ten ostatni wyśle ​​komunikat informujący, że wyjeżdżamy, a od _closing teraz to prawda, strumień zostanie później usunięty.