2014-11-21 20 views
5

Tôi đã cố gắng tạo một ứng dụng khách IRC cho ứng dụng Windows Phone 8.1 của mình và tôi đã may mắn tìm được một hướng dẫn thực sự tốt. Thật không may là hướng dẫn cho WP 7 và WP 8.1 MS đã thay đổi nó thành các ứng dụng thời gian chạy, có nghĩa là SocketAsyncEvents không có sẵn cho tôi (mặc dù MSDN nói nó hỗ trợ 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); 
} 

Đào xung quanh tôi thấy rằng các ổ cắm đã được chuyển sang Windows.Networking.Sockets, nhưng chưa có ổ cắm nào chứa SocketAsyncEvents.

tôi khá nhiều không thể đi xa hơn từ đây, không ai có một ý tưởng về làm thế nào để chuyển đổi chức năng để nói một cái gì đó sẽ làm việc với WP 8.1?

+0

Dự án của bạn là Windows Phone 8.1 Runtime (ứng dụng toàn cầu) hoặc Windows 8.1 silverlight? – crea7or

+0

Tôi tìm thấy một giải pháp, tôi sẽ được cập nhật bài đăng này ngay sau khi tôi hoàn thành viết một lớp cho nó :) cảm ơn vì đã quan tâm mặc dù. Và có, đó là thời gian chạy :) – Jazerix

Trả lời

4

Đây rồi!

Sau rất nhiều nghiên cứu này là những gì tôi tìm thấy:

Trước hết chúng tôi đã nhận một phương pháp kết nối.

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; 

} 

Để đọc dữ liệu chúng tôi nhận được thông qua các StreamSocket, chúng ta tạo ra một phương pháp readData() và làm cho nó đệ quy vì vậy chúng tôi sẽ tiếp tục nhận được các dữ liệu:

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

Bây giờ chúng ta có hai phương pháp mới , SendIdentity();ReplyPong(string message); Thông thường các máy chủ IRC sẽ ping bạn, ở đây bạn phải trả lời với một pong, như vậy:

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

và chúng tôi cũng phải gửi bản sắc của chúng tôi khi máy chủ đã sẵn sàng cho nó, như vậy:

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

Cuối cùng chúng ta có phương pháp SendRawMessage(); của chúng tôi, gửi dữ liệu đến máy chủ.

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

Hầu như quên ra chức năng dispose, mà bạn có thể gọi khi bạn muốn đóng dòng :)

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

này sẽ gửi một tin nhắn cuối cùng cho thấy rằng chúng ta đang đi, và kể từ _closing nay đúng, luồng sẽ được xử lý sau đó.

Các vấn đề liên quan