a11s.Net

年纪大了,脑子不好用了,需要记录写东西了

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  关键字: DirectPlay DPlay VB DirectX .net 网络 游戏 作者:董含君
转贴请注明来自 http://a11s.cnblogs.com

这个QQ群的问题很是难办…. 人数已经超了….包括分群也超了…..对不住大家了

或者跟dudu老大联系一下开一个托管的DirectX 俱乐部或者团队之类的,指望QQ是靠不住了….

身体还是比较虚弱.继续加营养….下次就是看大厅了lobby还有Server以及Client还有Voice,周末回家养病,不一定能完成多少.

今天看了关于HostMigration的演示.就是HOST迁移.这个….还是举例子吧(赵本山:”转移了!”)



星际争霸
魔兽争霸 帝国时代 红色警戒…. 之类的联机游戏

1 网络游戏的时候我们都是需要先选择连线方式(帝国时代1最经典,简直就是专门为DPlay做的DEMO!!不信你连连看,就是当年DX7的那些窗体) 这个对应我们addressServiceProvider 比如tcpip ipx modem..

2 然后需要有一个人做HOST 创建游戏. Peer.host()

3 大家加入 Peer.connect()

4 游戏开始 Peer.sendto() 发送数据

5 玩家2挂了,退出了,去参与其他游戏了,但是剩下的7个人(假设原来一共8)还在继续少一个人罢了

6 终于玩家1(创建游戏的人)挂了.剩下六个人,按理说不就是少了一个人嘛.但是游戏是他创建的..这样就 

实际上,星际或者魔兽的时候还是可以继续的.这一点不同于CS模式(客户端-服务器)如果哪天WOW服务器当机了估计有一大票人都得休息

这个解决的办法就是HostMigration 玩家1挂了,甚至断线了.停电了.session并没有中止,剩余的玩家将会有人接替玩家1的任务. 最重要的是,这一切都非常简单!

(这一点不知道能不能用在服务器的故障转移上面.呵呵,我学DX的目的并不完全都是准备用来做游戏毕竟还是服务器跟桌面程序才是老本行..如果有多台服务器负载均衡,使用IPX,然后有一台网管对外.这样数据处理挂掉一台自然可以平滑迁移,而且由于不见得要求IP地址,所以一般的黑客工具或者入侵方式可能会遇上点麻烦,当然仅仅是想法而已没有认真考虑,可能有不现实的地方,以后再说了)

7 终于最后一个玩家退出游戏,整个session结束.

 

以上就是游戏(网络)的进行过程,同时给出了类,方法的对照

 

实现过程很简单,如果你一路看我的blog的话,这样的基础已经可以了.创建appdesc的时候有个flag添加上这个 AppDesc.Flags = AppDesc.Flags Or SessionFlags.MigrateHost 然后准备响应一个事件

AddHandler m_Peer.HostMigrated, AddressOf HostMigratedHandler 用自定义的方法HostMigratedHandler()来响应 peer.hostmigrated.无非就是判断一下自己是不是host(其实,不理睬他也是可以的,p2p是对等的嘛,谁当老大都一样,反正真正的老大已经没了,通过事件返回的HostMigratedEventArgs来找到目的HOST的信息) OK,就需要注意这两个地方.

代码就不全贴出来了,这次直接COPY 微软的.体会一下就可以了.或者等我找到空间之后给出源码下载地址.

主要就是看看HostMigratedHandler,其他的都像上一篇一样不便.自己改一下就可以了,如果你真的理解了的话以下仅供参考,不要直接复制.

        Public Sub ReceiveHandler(ByVal sender As Object, ByVal args As ReceiveEventArgs)

            If m_Form.ReceivedMessagesListBox.Enabled Then

                ' Read the incoming chat message. Since network data is always

                ' broken down into raw bytes for transfer, the sent object must

                ' be rebuilt. The NetworkPacket class contains methods to

                ' easily send and receive unicode strings, but this sample

                ' manually decodes the string for compatibility with the C++

                ' tutorials. The data is first read into a byte array, then Unicode

                ' decoded, and finally added to our list of received messages.

                Dim packet As NetworkPacket = args.Message.ReceiveData

                Dim data As Byte() = CType(packet.Read(GetType(Byte), packet.Length), Byte())

                m_Form.ReceivedMessagesListBox.Items.Add(Encoding.Unicode.GetString(data))

            End If

        End Sub 'ReceiveHandler

 

        '/ <summary>

        '/ Handler for incoming DirectPlay HostMigrated events

        '/ </summary>

        Public Sub HostMigratedHandler(ByVal sender As Object, ByVal args As HostMigratedEventArgs)

            Dim info As PlayerInformation = m_Peer.GetPeerInformation(args.Message.NewHostID)

 

            ' See if we are the new host

            If info.Local Then

                m_Connection = ConnectionType.Hosting

                UpdateUI()

            End If

        End Sub 'HostMigratedHandler

 

        '/ <summary>

        '/ Handler for incoming DirectPlay SessionTerminated events

        '/ </summary>

        Public Sub SessionTerminatedHandler(ByVal sender As Object, ByVal args As SessionTerminatedEventArgs)

            MessageBox.Show(m_Form, "Connect lost or host terminated session", "DirectPlay Tutorial")

            m_Connection = ConnectionType.Disconnected

            UpdateUI()

        End Sub 'SessionTerminatedHandler

 

        '/ <summary>

        '/ Host a new DirectPlay session.

        '/ </summary>

        Public Sub HostSession()

            ' Get desired hosting options

            Dim dialog As New HostDialog()

            dialog.LocalPort = DefaultPort

 

            If DialogResult.Cancel = dialog.ShowDialog() Then

                Return

            End If

            ' Update the UI

            m_Form.SessionStatusLabel.Text = "Connecting..."

            m_Form.Update()

 

            ' Store host dialog choices

            m_SessionName = dialog.SessionName

 

            ' Add the port number

            If dialog.LocalPort > 0 Then

                m_LocalAddress.AddComponent("port", dialog.LocalPort)

            End If

 

            ' Create an application description

            Dim AppDesc As New ApplicationDescription()

            AppDesc.GuidApplication = m_AppGuid

            AppDesc.SessionName = m_SessionName

            AppDesc.Flags = SessionFlags.NoDpnServer

 

            If dialog.IsHostMigrationEnabled Then

                AppDesc.Flags = AppDesc.Flags Or SessionFlags.MigrateHost

            End If

 

            Try

                ' Host a new session

                m_Peer.Host(AppDesc, m_LocalAddress) ' Application description

                ' Local device address

                m_Connection = ConnectionType.Hosting

            Catch ex As Exception

                m_Form.ShowException(ex, "Host", True)

                m_Form.Dispose()

                Return

            End Try

        End Sub 'HostSession

 

        '/ <summary>

        '/ Find all sessions at the given host address

        '/ </summary>

        '/ <param name="hostname">IP address or hostname to search</param>

        '/ <param name="port">Remote port to search</param>

        Public Sub EnumerateSessions(ByVal hostname As String, ByVal port As Integer)

            ' Set the desired search options

            Dim HostAddress As New Address()

            HostAddress.ServiceProvider = Address.ServiceProviderTcpIp

 

            If hostname.Length > 0 Then

                HostAddress.AddComponent("hostname", hostname)

            End If

 

            If port > 0 Then

                HostAddress.AddComponent("port", port)

            End If

 

            Dim AppDesc As New ApplicationDescription()

            AppDesc.GuidApplication = m_AppGuid

 

            ' Find all sessions hosted at the given address. When a session is

            ' found, DirectPlay calls our FindHostResponse delegate. Since we're

            ' passing in the "Sync" flag, Connect will block until the search

            ' timeout has expired.

            Try

                m_Peer.FindHosts(AppDesc, HostAddress, m_LocalAddress, Nothing, 0, 0, 0, FindHostsFlags.Sync) ' Application description

                ' Host address

                ' Local device address

                ' Enumeration data

                ' Enumeration count (using default)

                ' Retry interval (using default)

                ' Timeout (using default)

                ' Flags

            Catch ex As Exception

                m_Form.ShowException(ex, "FindHosts", True)

                m_Form.Dispose()

                Return

            End Try

        End Sub 'EnumerateSessions

 

        '/ <summary>

        '/ Connect to the currently selected session

        '/ </summary>

        Public Sub ConnectToSession()

            ' Display connection dialog

            Dim dialog As New ConnectDialog(Me)

            dialog.RemotePort = DefaultPort

 

            If DialogResult.Cancel = dialog.ShowDialog() Then

                Return

            End If

            ' Update the UI

            m_Form.SessionStatusLabel.Text = "Connecting..."

            m_Form.Update()

 

            ' Store connection dialog choices

            Dim SelectedHost As HostInfo = dialog.SelectedHost

            If SelectedHost Is Nothing Then

                Return

            End If

            ' Create an application description object to hold the desired

            ' host's instance guid.

            Dim appDesc As New ApplicationDescription()

            appDesc.GuidInstance = SelectedHost.GuidInstance

 

            ' Attempt to connect to the selected DirectPlay session. Once we

            ' are connected to the session, we will receive DirectPlay messages

            ' about session events (like players joining/exiting and received game

            ' data). Since we're passing in the "Sync" flag, the Connect call will

            ' block until the session is connected or the timeout expires.

            Try

                m_Peer.Connect(appDesc, SelectedHost.HostAddress, m_LocalAddress, Nothing, ConnectFlags.Sync) ' Application description

                ' Host address

                ' Local device address

                ' User connection data (none) 

                ' Flags

                m_SessionName = SelectedHost.SessionName

                m_Connection = ConnectionType.Connected

            Catch ex As Exception

                m_Form.ShowException(ex, "Connect", False)

                Return

            End Try

        End Sub 'ConnectToSession

 

        '/ <summary>

        '/ Sends the current outgoing chat string to all connected peers

        '/ </summary>

        Public Sub SendData()

            ' Create a network packet object to which we can write our chat message.

            ' For compatibility with the current C++ tutorials, the unicode text

            ' will be encoded as a null-terminated string for network transfer, as

            ' opposed to the .NET convention of string length followed by characters;

            ' however, there are no limits on how the data can be formatted since

            ' all data is received as a raw byte array.

            Dim packet As New NetworkPacket()

            packet.Write(Encoding.Unicode.GetBytes(m_Form.SendTextBox.Text))

 

            ' Now that all the outgoing data has been encoded to a network

            ' packet, the DirectPlay send method can be called. Since in a

            ' peer-to-peer topology there is no server, you must inform

            ' DirectPlay which peer you wish to receive the data. For this

            ' sample, we'll deliver the message to all connected players

            ' (except the local player, which we exclude with the NoLoopback

            ' flag )

            m_Peer.SendTo(CInt(PlayerID.AllPlayers), packet, 0, SendFlags.Sync Or SendFlags.NoLoopback) ' Send to session

            ' Outgoing data

            ' Timeout (default)       

            ' Flags

 

            m_Form.SendTextBox.Text = ""

        End Sub 'SendData

 

        '/ <summary>

        '/ Terminate or disconnect from the session.

        '/ </summary>

        Public Sub Disconnect()

            ' Disconnect by closing the current peer and opening

            ' a new one.

            InitDirectPlay()

            UpdateUI()

        End Sub 'Disconnect

posted on 2005-11-03 16:50  a11s.net  阅读(2282)  评论(0编辑  收藏  举报