关闭服务
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线程挂死。