Windows Moible, Wince 使用.NET Compact Framework的進行藍芽(Bluetooth)廣播程式的開發

來源:互聯網
上載者:User
文章目錄
  • 成員定義
  • 啟動服務
  • 監聽線程
  • 廣播線程
  • 關閉服務
  • UI處理
  • 發現
  • 訂閱
  • 接收訊息
簡述

本文講述如何使用32feet.NET實現Bluetooth的廣播程式,同時示範了Broadcom stack在Windows Mobilie下的實現。

背景

在.NET Compact Framework下的Bluetooth開發 之 32feet.NET 的反饋中 camper9999 同學希望實現藍芽廣播的功能,本文就是一個基於32feet.NET藍芽廣播的實現。

sammylp 的提出代碼掛死問題,其實是使用過程的不恰當造成的,本文示範如何使用線程防止UI線程的掛起,程式的假死。

另外一個同學(不好意思忘記哪位了)問32feet.NET是否支援Broadcom stack,所以本文的實現運行於安裝Broadcom stack的windows mobile中。

感謝各位的反饋,現在盡量在一篇文章中回答。

關於Bluetooth開發的也可以參考以下其他文章:

.NET Compact Framework下的Bluetooth開發 之 Windows Embedded Source Tools for Bluetooth

.NET Compact Framework下的Bluetooth開發 之 32feet.NET

.NET Compact Framework下的Bluetooth開發 之 Bluetooth Virtual Serial Port

.NET Compact Framework下的Bluetooth裝置的配對

30 Days of .NET [Windows Mobile Applications] - Day 02: Bluetooth Manager(藍芽管理器)

什麼是廣播

所謂廣播就是訊息發送方向公眾(public)發送資訊的過程,廣播有一個主要的特點是訊息發送方不需要知道訊息接收方的存在。現實生活中廣播的例子如收音機廣播,GPS衛星廣播,乙太網路同網段資料包的廣播等等。可是所謂藍芽廣播其實不算嚴格下的廣播,因為藍芽通訊過程中有發現,配對,甚至驗證過程,所以通訊雙方是需要握手的,沒辦法實現嚴格意義上的廣播。本文例子實現了一個通過註冊訂閱者式的組播過程(MultiCast)。

 

實現服務端

服務端負責監聽和註冊服務,同時把訊息發送到已經註冊的裝置去。在例子中服務端使用PC實現,其實可以使用Windows Mobilie作為服務端,32feet.net庫基本相容PC和CE。

成員定義
private BluetoothListener listener;
private bool listening = true;
private List<BluetoothClient> clientList = new List<BluetoothClient>();
private System.Threading.Thread listenThread;
private System.Threading.Thread broadcastThread;

listener負責監聽服務,clientList 存放已經註冊的裝置,listenThread負責監聽的線程,broadcastThread負責廣播的線程。

啟動服務
BluetoothRadio radio = BluetoothRadio.PrimaryRadio;
if (radio == null)
{
WriteMessage("No radio hardware or unsupported software stack");
return;
}

// Enable discoverable mode
radio.Mode = RadioMode.Discoverable;
WriteMessage("Radio Name:" + radio.Name);
WriteMessage("Radio Address:" + radio.LocalAddress);
WriteMessage("Radio Mode now: " + radio.Mode.ToString());

listener = new BluetoothListener(BluetoothService.SerialPort);
listener.Start();

listening = true;
listenThread = new System.Threading.Thread(ListenLoop);
broadcastThread = new System.Threading.Thread(BroadcastLoop);
listenThread.Start();
broadcastThread.Start();
WriteMessage("Service started!");

啟動服務的流程是:

1.檢查藍牙裝置是否準備好。

2.設定藍牙裝置為可發現。

3.啟動藍芽監聽,這裡配置的服務類型為串口服務,在用戶端也需要配置串口服務類型才能進行通訊。

4.啟動監聽線程,這樣不會掛死主線程(Main Thread)。

5.啟動廣播線程。

監聽線程
private void ListenLoop()
{
byte[] buffer = new byte[4];
string dataToSend = "Thanks for subscription";
byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(dataToSend);

while (listening)
{
try
{
BluetoothClient client = listener.AcceptBluetoothClient();
WriteMessage("Get a subscription from " + client.RemoteMachineName);
clientList.Add(client);
System.IO.Stream ns = client.GetStream();
ns.Write(dataBuffer, 0, dataBuffer.Length);
}
catch
{
break;
}
}
listener.Stop();
}

監聽線程負責處理監聽訂閱請求,並把訂閱的裝置增加到訂閱列表中。AcceptBluetoothClient()會掛起改線程,直到有新的裝置進行訂閱。

廣播線程
private void BroadcastLoop()
{
List<BluetoothClient> tempClientList = new List<BluetoothClient>();

while (listening)
{
System.Threading.Thread.Sleep(5000);

string dataToSend = "Broadcast Message at " + System.DateTime.Now.ToLongTimeString();
byte[] dataBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(dataToSend);

tempClientList.Clear();
foreach (BluetoothClient client in clientList)
{
try
{
System.IO.Stream ns = client.GetStream();
ns.Write(dataBuffer, 0, dataBuffer.Length);
WriteMessage("Sent message to " + client.RemoteMachineName);
}
catch
{
//connection is broken.
tempClientList.Add(client);
continue;
}
}

//clean up the broken connections.
foreach (BluetoothClient client in tempClientList)
{
clientList.Remove(client);
}
}
}

廣播線程負責對已經訂閱的裝置進行訊息廣播,同時管理已經中斷的超連結。在實際應用中,這個線程需要根據需求來更改商務程序。

關閉服務
WriteMessage("Service stop!");
listening = false;
if (listener != null)
{
listener.Stop();
}

釋放監聽資源。

UI處理

由於使用了多線程,不能直接更新UI,所以需要藉助delegate和Invoke()函數來更新。

public delegate void SafeWinFormsThreadDelegate(string msg);
private void WriteMessage(string msg)
{
SafeWinFormsThreadDelegate d = new SafeWinFormsThreadDelegate(UpdateUi);
Invoke(d, new object[] { msg });
}

private void UpdateUi(string msg)
{
if (listBoxMsg.Items.Count > 100)
{
listBoxMsg.Items.RemoveAt(0);
}
listBoxMsg.SelectedIndex = listBoxMsg.Items.Add(msg);
}

 

用戶端

用戶端負責探索服務端裝置,同時發起訂閱請求,然後接收廣播訊息。用戶端使用安裝了BroadCom stack的Windows Mobile實現,實際上同時支援MS stack。

發現
BluetoothRadio radio = BluetoothRadio.PrimaryRadio;
if (radio == null)
{
WriteMessage("No radio hardware or unsupported software stack");
return;
}

//Broadcom stack doesn't support the functionality to turn on the bluetooth, turn it on manually please
//radio.Mode = RadioMode.Connectable;

//Scan the nearby devices
listBoxDevices.Items.Clear();
BluetoothDeviceInfo[] devices = client.DiscoverDevices();
listBoxDevices.DataSource = devices;
listBoxDevices.DisplayMember = "DeviceName";
listBoxDevices.ValueMember = "DeviceAddress";

WriteMessage("Discover successful, please select one device to subscribe.");

由於目前的版本的32feet.net在BroadCom stack下不支援設定藍芽狀態,所以如果裝置是BroadCom stack需要屏蔽設定藍芽狀態的語句。把發現到的裝置顯示到ListBox裡面。

訂閱
BluetoothAddress deviceAddress = listBoxDevices.SelectedValue as BluetoothAddress;
client.Connect(deviceAddress, BluetoothService.SerialPort);
WriteMessage("Connected to " + client.RemoteMachineName);
stream = client.GetStream();
receiving = true;
System.Threading.Thread t = new System.Threading.Thread(ReceiveLoop);
t.Start();

根據發現的服務端裝置的地址進行串連,然後啟動線程接收訊息。

接收訊息
private void ReceiveLoop()
{
byte[] buffer = new byte[255];

while (receiving)
{
if (stream.CanRead)
{
stream.Read(buffer, 0, 255);
string data = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, 255);
WriteMessage(data);
}
}
}

線上程裡接收訊息,避免主UI線程掛死。

 

原始碼:http://files.cnblogs.com/procoder/BtBroadcast.rar

平台:Visual Studio 2008 + Windows Mobile 5 Packet PC SDK

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.