#c# #asynchronous #bluetooth #discovery
#c# #асинхронный #bluetooth #обнаружение
Вопрос:
Я пытаюсь использовать 32 фута.СЕТЕВАЯ библиотека bluetooth в приложении C # для обнаружения близлежащих устройств. Цель моего небольшого приложения — сообщить компьютеру, кто находится в комнате, используя функцию Bluetooth мобильных телефонов людей.
Лучший способ сделать что-то подобное — позволить устройствам, которые я хочу «отслеживать», подключиться один раз, а затем постоянно проверять, можно ли их обнаружить через Bluetooth.
Теперь мои вопросы:
-
Нужно ли мне выполнять сопряжение или аутентификацию устройства с моим приложением? Как это сделать в C # с 32feet.NET ?
-
Как постоянно проверять наличие устройств в радиусе действия и сравнивать их с сохраненными устройствами?
Я знаю, что все это, вероятно, есть в документации библиотеки, но мне действительно трудно читать, и большинство примеров, похоже, находятся в VB, который я не знаю, и его трудно перевести на C # (особенно когда дело доходит до асинхронных вызовов и тому подобного).
Я был бы очень рад, если бы кто-нибудь мог подтолкнуть меня в правильном направлении!
Ответ №1:
Сразу оговорюсь, я предполагаю, что вы здесь не имеете дело со скрытыми устройствами, они обычно обрабатываются ОС. Я также только начал использовать 32feet, и я использую его для создания подключений к службе последовательного порта в сканерах штрих-кодов Bluetooth, поэтому для ваших нужд могут быть лучшие способы, но это может указать вам правильное направление для начала.
Вам нужно выполнить сопряжение устройства, да. Если вы используете его в приложении WinForms, на самом деле вы можете отобразить форму, которая обрабатывает сканирование устройств и позволяет выбрать одно из них, например:
bool PairDevice()
{
using (var discoverForm = new SelectBluetoothDeviceDialog())
{
if (discoverForm.ShowDialog(this) != DialogResult.OK)
{
// no device selected
return false;
}
BluetoothDeviceInfo deviceInfo = discoverForm.SelectedDevice;
if (!deviceInfo.Authenticated) // previously paired?
{
// TODO: show a dialog with a PIN/discover the device PIN
if (!BluetoothSecurity.PairDevice(deviceInfo.DeviceAddress, myPin))
{
// not previously paired and attempt to pair failed
return false;
}
}
// device should now be paired with the OS so make a connection to it asynchronously
var client = new BluetoothClient();
client.BeginConnect(deviceInfo.DeviceAddress, BluetoothService.SerialPort, this.BluetoothClientConnectCallback, client);
return true;
}
}
void BluetoothClientConnectCallback(IAsyncResult result)
{
var client = (BluetoothClient)result.State;
client.EndConnect();
// get the client's stream and do whatever reading/writing you want to do.
// if you want to maintain the connection then calls to Read() on the client's stream should block when awaiting data from the device
// when you're done reading/writing and want to close the connection or the device servers the connection control flow will resume here and you need to tidy up
client.Close();
}
Безусловно, лучший способ, если ваши устройства передают, что они доступны для подключения, — это настроить a BluetoothListener
, который будет постоянно прослушивать устройства вещания, и когда один из них будет найден, вы получите BluetoothClient
экземпляр, который вы можете использовать так же, как при первом сопряжении:
void SetupListener()
{
var listener = new BluetoothListener(BluetoothService.SerialPort);
listener.Start();
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
}
void BluetoothListenerAcceptClientCallback(IAsyncResult result)
{
var listener = (BluetoothListener)result.State;
// continue listening for other broadcasting devices
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
// create a connection to the device that's just been found
BluetoothClient client = listener.EndAcceptBluetoothClient();
// the method we're in is already asynchronous and it's already connected to the client (via EndAcceptBluetoothClient) so there's no need to call BeginConnect
// TODO: perform your reading/writing as you did in the first code sample
client.Close();
}
Менее привлекательный, но полезный, если ваше устройство не транслирует соединения, вы можете создать новое BluetoothClient
и попросить его вернуть все устройства, которые он может найти:
void ScanForBluetoothClients()
{
var client = new BluetoothClient();
BluetoothDeviceInfo[] availableDevices = client.DiscoverDevices(); // I've found this to be SLOW!
foreach (BluetoothDeviceInfo device in availableDevices)
{
if (!device.Authenticated)
{
continue;
}
var peerClient = new BluetoothClient();
peerClient.BeginConnect(deviceInfo.DeviceAddress, BluetoothService.SerialPort, this.BluetoothClientConnectCallback, peerClient);
}
}
Ответ №2:
Это не ответ, но я не смог поместить столько кода в раздел комментариев. Измените эти строки кода:
//continue listening for other broadcasting devices
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
// create a connection to the device that's just been found
BluetoothClient client = listener.EndAcceptBluetoothClient();
Для
// create a connection to the device that's just been found
BluetoothClient client = listener.EndAcceptBluetoothClient();
// continue listening for other broadcasting devices
listener.BeginAcceptBluetoothClient(this.BluetoothListenerAcceptClientCallback, listener);
В основном, измените последовательность кода..
Что касается каждого вызова метода BeginXXXX, то он должен иметь следующий EndXXXX. И во всем приведенном выше коде вы пытаетесь начать acceptbluetoothclient поверх уже начатого «BeginAcceptBluetoothClient».
Надеюсь, вы понимаете.