我目前正在開發一個需要通過套接字連接與MQTT服務器進行通信的應用程序。由於System.Net.Sockets API在從WiFi網絡切換到3G網絡時往往會出現問題(實際上這種情況非常多),所以我決定嘗試使用CFStream API。這樣做我遇到了幾個問題,如下所示。MonoTouch和CFStream API的問題
一旦我在任何一個流上調用Open(),立即創建一對包含CreatePairWithSocketToHost
的流。
CFStream.CreatePairWithSocketToHost(GetEndPoint(), out mReadStream, out mWriteStream);
mReadStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mWriteStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mReadStream.Open();
mWriteStream.Open();
無論我是否撥打EnableEvents()
,都會發生崩潰。唯一的例外是:
[ERROR] FATAL UNHANDLED EXCEPTION: MonoTouch.CoreFoundation.CFException: The operation couldn’t be completed. Cannot allocate memory
at MonoTouch.CoreFoundation.CFStream.CheckError() [0x0000f] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreFoundation/CFStream.cs:236
at MonoTouch.CoreFoundation.CFStream.Open() [0x00040] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreFoundation/CFStream.cs:248
at TestCfNework.RootViewController.TestCreatePairToHost() [0x00041] in /Users/adrian/Projects/TestCfNework/TestCfNework/RootViewController.cs:79
at TestCfNework.RootViewController.ViewDidLoad() [0x00000] in /Users/adrian/Projects/TestCfNework/TestCfNework/RootViewController.cs:24
at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible() [0x00008] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWindow.g.cs:124
at TestCfNework.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options) [0x0002e] in /Users/adrian/Projects/TestCfNework/TestCfNework/AppDelegate.cs:32
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at TestCfNework.Application.Main (System.String[] args) [0x00000] in /Users/adrian/Projects/TestCfNework/TestCfNework/Main.cs:17
創建具有CreatePairWithSocket
一對流首先創建和連接CFSocket
允許Open()
沒有崩潰繼續,但CanAcceptBytesEvent
是從來沒有發射,CanAcceptBytes()
始終是假的,任何寫入失敗了時間到。
mSocket = new CFSocket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp,
CFRunLoop.Current);
mSocket.ConnectEvent += delegate {
Console.WriteLine("Socket connected");
CFStream.CreatePairWithSocket(mSocket, out mReadStream, out mWriteStream);
mReadStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mWriteStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mReadStream.Open();
mWriteStream.Open();
mWriteStream.CanAcceptBytesEvent += delegate {
Console.WriteLine("Write stream can now accept data");
};
mWriteStream.ErrorEvent += delegate {
Console.WriteLine(mWriteStream.GetError());
};
};
mSocket.Connect(GetEndPoint(), 0);
創建一個對使用CreatePairWithPeerSocketSignature
流的是實際產生一對,我可以工作流的只有一個:開放不會崩潰,我允許寫入和讀取各個。
API在模擬器和實際設備上的行爲都是這樣。所以,這是我做錯了什麼?這是MonoTouch的問題嗎?它是CFStream API本身的錯誤嗎?
MonoTouch版本:6.0.1。 XCode版本:4.5。
想知道您最終使用哪個MQTT庫,還是正在開發自己的? –
這兩個,實際上:我目前使用這個庫http://sourceforge.net/projects/mqttdotnet/(雖然它需要一些調整),同時我正在開發自己的。 – AlexB
啊是的我猜這個庫不符合3.1。很想在某個階段看到你的圖書館,如果適合,很樂意列在mqtt.org網站上。 –