同城约会| 杂志期刊| 小说| 两性论坛| 军事电影| 两性知识| 电脑知识| 汽车| 旅游| 收藏

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

来源:J2ME开发网 作者:mydeman编… 出处:综艺读书 2006-10-16 
关 键 词:协议  数据库  服务器  xml  os  

放眼市场上各种各样的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

更多文章 更多内容请看FTP服务器  IIS服务器应用技巧  IMail服务器专题,或进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
综艺读书宗旨
相关专题
·FTP服务器 (5042篇文章)
·双核服务器技术 (5542篇文章)
·网站服务器的选型 (6600篇文章)
·网吧流媒体服务器 (5311篇文章)
·刀片服务器专题 (4616篇文章)
·网吧服务器专栏 (4528篇文章)
·网络管理实用手册 (18187篇文章)
·服务器配置专栏 (8814篇文章)
·IIS服务器应用技巧 (5103篇文章)
·打造安全服务器 (11204篇文章)
热点标签: 协议  数据库  服务器  xml  os  
最新技术文档
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
百度推荐,商机无限
搜索您感兴趣的内容
Web 全站
综艺电脑频道编辑信箱  告诉我们您想看的专题或文章

Google

友情互链 | 收藏本站 | 联系我们 | 在线留言 | 京ICP备08008424号|