WEB开发网
开发学院软件开发Java 关于管理蓝牙SDP记录和游戏服务器之间连接的若干建... 阅读

关于管理蓝牙SDP记录和游戏服务器之间连接的若干建议

 2007-12-23 12:31:50 来源:WEB开发网   
核心提示:放眼市场上各种各样的JSR82 MIDlets,有一点需要注意,关于管理蓝牙SDP记录和游戏服务器之间连接的若干建议,一些MIDlets并没有以一种合适的方式处理服务发现协议(SDP)记录,在蓝牙领域内SDP记录是非常难以领会的,当然,在你可以的应用中可能包括多于一个的SDP记录,但是在JSR82中并没有这么困难,这篇

放眼市场上各种各样的JSR82 MIDlets,有一点需要注意,一些MIDlets并没有以一种合适的方式处理服务发现协议(SDP)记录。在蓝牙领域内SDP记录是非常难以领会的,但是在JSR82中并没有这么困难。

这篇短小的文章会就SDP记录的一般问题给予一些建议。

我们先简要地看看为什么需要SDP记录。SDP记录是一种用来确认设备上的一种特定服务的记录。没有SDP记录,一部移动电话就不可能检测到另一个设备上的服务。大部分的电话拥有一个以上的SDP记录,例如,它们很可能有对于L2CAP和串口的记录。

关于SDP记录最主要的问题的就是很多开发者忘记了从数据库中删除SDP记录。这就导致了最终用户不能重新连接来运行游戏。

下面两张简单的图片说明了这个问题:

关于管理蓝牙SDP记录和游戏服务器之间连接的若干建议(图一)

图1  SDP连接成功

如图1所示两个MIDlets正在试图进行连接,并且连接成功。

关于管理蓝牙SDP记录和游戏服务器之间连接的若干建议(图二)

图2 SDP连接失败

在图2中我们可以看到,一个MIDlet再一次尝试连接(可能是同一用户或者一个新用户)。连接失败,因为这个MIDlet试图连接的SDP记录没有监听器,所以Bluetooth栈除了拒绝连接别无选择。经常发生的情况是,客户端MIDlet接收到两者的SDP记录,但是只选择第一个进行连接,因为它只希望在一个服务器上有一个SDP记录。

在下面的代码示例中了,展示了一个简单的服务器。这个例子关注了必须的close()调用。

例子:


public class SEMCSPPServer extends Thread
{
  PRivate StreamConnectionNotifier server = null;
  private StreamConnection sppConnection = null;

  public SEMCSPPServer()
  {
   // This will create create an SDP record in the dB
   try
   {
    server = (StreamConnectionNotifier)Connector.open( "BTspp://localhost:ea834a8566aa4e0fb02ce4c1a53700c9;name=SomeServer" );
   }
   catch( Exception e ) {}
  }

  public void run()
  {
   // Wait for connections
   try
   {
    sppConnection = server.acceptAndOpen();
   }
   catch( Exception e ) { e.printStackTrace(); }

   // Let the server do something fun here

   try
   {
    // Open the Streams to be used for communications
    InputStream in = sppConnection.openInputStream();
    OutputStream out = sppConnection.openOutputStream();
     
    // Let the server do something fun here
    while()
    {
    }

    // Server is done, now cleanup


    // Close the Streams
    try
    {
     in.close();
    }
    catch( IOException ioe ) {}
    try
    {
     out.close();
    }
    catch( IOException ioe ) {}

    in = null;
    out = null;
   }
   catch( Exception e ) {}


   // Close the Connection
   try
   {
    sppConnection.close();
   }
   catch( IOException ioe ) {}
   sppConnection = null;

   // To make it possible for a client to re-connect
   //  we need to remove the current SDP record
   // If the MIDlet ends here we SHOULD still
   //  close the notifier, but the MIDlet environment will
   //  clean-up after us
   server.close();
  } // run
}

自然地,你就拥有了几种类型不同的服务器管理者,它们管理所有的服务器连接,并且使SDP记录重新利用,例如,有一种服务器管理者始终监听连接。例如,在一个多玩家的蓝牙游戏中允许玩家随时进入和退出。

服务器管理者例子:

// A simple server handler
public class SEMCSPPServerHandler
{
  private StreamConnectionNotifier server = null;
  private StreamConnection sppConnection = null;

  public SEMCSPPServerHandler()
  {
   // This will create create an SDP record in the dB
   try
   {
    server = (StreamConnectionNotifier)Connector.open( "btspp://localhost:ea834a8566aa4e0fb02ce4c1a53700c9;name=SomeServer" );
   }
   catch( Exception e ) {}


   while( true )
   {
    // Wait for connections
    try
    {
     sppConnection = server.acceptAndOpen();
    }
    catch( Exception e ) { e.printStackTrace(); }

  if( sppConnection != null )
    {
     SEMCSPPServer sp = new SEMCSPPServer( sppConnection );
     sp.start();
     sp = null;
    }
    // The server handler is now ready to deal with new connections
    // Note, there is no need to create a new SDP record
   }


   // Remove the SDP record
   server.close();
  }
}

// A simple server class to deal with 1 connection
public class SEMCSPPServer extends Thread
{
  private StreamConnection sppConnection = null;

  public SEMCSPPServer( StreamConnection sppConnection )
  {
   this.sppConnection = sppConnection;
  }

  public void run()
  {
   try
   {
    // Open the Streams to be used for communications
    InputStream in = sppConnection.openInputStream();
    OutputStream out = sppConnection.openOutputStream();
     
    // Let the server do something fun here
    while()
    {
    }
    // Server is done, now cleanup


    // Close the Streams
    try
    {
     in.close();
    }
    catch( IOException ioe ) {}
    try
    {
     out.close();
    }
    catch( IOException ioe ) {}

    in = null;
    out = null;
   }
   catch( Exception e ) {}

   // Close the Connection
   try
   {
    sppConnection.close();
   }
   catch( IOException ioe ) {}
   sppConnection = null;
   // The server is no longer active
  } // run

}

需要学习的经验

如果Connector. open()调用没有很好的管理,除非退出MIDlet(这种情况下SDP数据库被在一个清空)否则要重新连接到那个SDP记录是不可能的。现实生活中,你必须要退出游戏然后重新启动,这将会使最终用户灰心地离开。

当然,在你可以的应用中可能包括多于一个的SDP记录,但是对于适当的功能性需求要确保MIDlet监听所有的记录。

原文地址:http://developer.sonyeriCSSon.com/site/global/techsupport/tipstrickscode/java/p_advice_bluetooth_sdp_game+server.jsp


(出处:http://www.cncms.com)


Tags:关于 管理 蓝牙

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接