用python来开发webgame服务端(3)

article/2025/9/13 18:38:42
刺鸟原创文章,转载请注明出处
    在之前的准备工作中,我们已经 建立了一个socket服务器 ,并且经过了 简单的测试 ,得到的结论是python可以满足我们的需求,那么接下来,我们要解决的是身为webgame服务端必须的几个功能模块:

     一、记录和维护所有客户机的状态
     更新:按照jinmin_lan同学的建议,这里直接用self.transport.sessionno即可,查twisted文档的时候我忽略了这个东西。因此无需按照我下面的方法来手动维护,好吧,我造了一次轮子……     

    为了实现这个功能,我们先回过头来分析下之前的服务端代码:
    1、每个客户端连接会有一个gameSocket对象被创建,然后触发connectionMade事件。
    2、客户端数据到达的时候触发dataReceived事件
    3、连接断开的时候触发connectionLost事件,然后对象被析构

    根据通常的处理思路,我们需要为每个客户端建立一个编号,即传说中的sockid,然后维护一个client和sockid之间的双向字典,以便我们能够简单的互相反查。我决定维护2份数据,以空间换时间,新建一个sockMana类来实现该功能:
  1. # sockmana.py
  2. class SockMana:
  3.     def __init__ (self):
  4.         self.sockNum = 0 #记录当前的在线总数
  5.         self.sockIndex = 1 #累加sockid
  6.         self.client2id = {} #保存client->sockid字典
  7.         self.id2client = {} #保存sockid->client字典
  8.     def addClient(self,client):
  9.         #增加一个客户端
  10.         print '** add client **'
  11.         self.sockNum = self.sockNum + 1
  12.         self.client2id[client] = self.sockIndex
  13.         self.id2client[self.sockIndex] = client
  14.         self.sockIndex = self.sockIndex + 1
  15.         print self.sockNum
  16.         print self.client2id
  17.         print self.id2client
  18.     
  19.     def delClient(self,client):
  20.         #删除一个客户端
  21.         print '** del client **'
  22.         if client in self.client2id:
  23.             self.sockNum = self.sockNum - 1
  24.             _sockid = self.client2id[client]
  25.             del self.client2id[client]
  26.             del self.id2client[_sockid]
  27.             print self.client2id
  28.             print self.id2client
  29.     
  30.     def getSockid(self,client):
  31.         #通过client获取sockid
  32.         if client in self.client2id:
  33.             return self.client2id[client]
  34.         else:
  35.             return None
  36.         
  37.     def getClient(self,sockid):
  38.         #通过sockid获取client
  39.         if sockid in self.id2client:
  40.             return self.id2client[sockid]
  41.         else:
  42.             return None    
  43. #初始化连接管理器
  44. sockMana = SockMana()

    接下来在我们的socket服务端代码中import它,并增加调用事件,然后略修改dataReceived事件,当收到客户端数据的时候,我们向客户端返回它的sockid,完整的服务端代码调整为:

  1. import os
  2. if os.name!='nt':
  3.     from twisted.internet import epollreactor
  4.     epollreactor.install()    
  5. else:
  6.     from twisted.internet import iocpreactor
  7.     iocpreactor.install()
  8. from twisted.internet.protocol import Factory,Protocol
  9. from twisted.internet import reactor
  10. from sockmana import sockMana
  11. class gameSocket(Protocol):
  12.     #有新用户连接至服务器
  13.     def connectionMade(self):
  14.         sockMana.addClient(self)
  15.         print 'New Client'
  16.     
  17.     #客户端断开连接
  18.     def connectionLost(self,reason):
  19.         sockMana.delClient(self)
  20.         print 'Lost Client'
  21.     
  22.     #收到客户端发送数据
  23.     def dataReceived(self, data):
  24.         print 'Get data:' + str(data)
  25.         #向该客户端发送数据
  26.         self.transport.write('your sockid is:'+ str(sockMana.getSockid(self)))
  27.     
  28. if __name__=='__main__':
  29.     f = Factory()
  30.     f.protocol = gameSocket
  31.     reactor.listenTCP(5200,f)
  32.     print 'server started...'
  33.     reactor.run()

    然后我们依然用telnet,来建立2个连接试试。
   

    可以看到,每增加一个客户端,我们的sockMana类中就会分别增加2个 key->val的键值对,通过sockMana.getSockid方法即可获取客户端的sockid,这样我们就为每个客户端建立了一个 唯一且可用于传递和储存 的数值编号,在以后的逻辑处理中,这将作为客户端的唯一标识。

    好了,我们断开其中一个客户端,看看我们的sockMana工作正常否?
    

    Yes!和预料中的一样,一切工作正常。我们又向前迈进了小小的一步,下面,我们得研究研究服务端如何和客户端之间高效的传输数据了。

#本文由 刺鸟 原创,欢迎转载,但请保留出处,也欢迎对本文感兴趣的同学多多交流。#

http://chatgpt.dhexx.cn/article/Cnp86FFP.shtml

相关文章

用python来开发webgame服务端

刺鸟原创文章,转载请注明出处 在开始之前,先简单描述一下项目的特点:我要实现的是一个mmorpg的webgame,地图上需要看到其他的玩家,战斗系统采用半回合制的模式,所谓的半回合制,即是:…

用python来开发webgame服务端(1)

http://ciniao.me/article.php?id9 刺鸟原创文章,转载请注明出处 在开始之前,先简单描述一下项目的特点:我要实现的是一个mmorpg的webgame,地图上需要看到其他的玩家,战斗系统采用半回合制的模式,所谓…

server: WebGame服务端架构分析

MMORPG服务器架构 一.摘要 1.网络游戏 MMORPG 整体服务器框架,包括早期,中期,当前的一些主流架构 2.网络游戏网络层,包括网络 协议 , IO 模型,网络框架,消息编码等。 3.网络游戏的 场景 管理, AI , 脚本 的应用等。 4.…

WebGame服务端架构分析(一)

做webgame也有段时间了,最近上线的游戏还处于起步阶段,第二个月收入突破100万了,跟市面上大的webgame比起来,根本不算什么,但有收入总比没有好,呵呵,以后还需更加努力。现在总结一下自己webgame的架构设计,总结的目的一方面是为了共享给网上的朋友,也希望网友给我提出…

Webgame服务端分布式架构设计

Webgame服务端分布式架构设计 ——By King 最近在设计实现Webgame服务端游戏架构,跟大家分享下。 以下对架构的几点说明: 1. DB:数据库层。使用MongoDB, 可以作分布式,按webgame的需求,基本应该是不需…

Vue3之获取DOM元素

简介 我们一般用ref函数来获取DOM元素 使用步骤 使用ref函数创建容器在需要获取的dom元素上写refdom元素保存在容器的value属性上 代码 <script setup> import {ref,onMounted} from "vue"const inputRef ref() onMounted(() > {console.log(inputRef…

vue中动态获取dom元素进行操作

这几天我远程面试了一家公司,期间问题我都回答上来了 但有一个问题我很纳闷 就是你说下vue中获取dom元素的方法吧 我说大体上俩中吧 1.vue中 ref的方法 给元素起一个ref名称 通过 this.$refs.ref名称获取 2.第二个无非是 原生dom操作了 document.getElement // document…

Vue笔记四:Vue获取DOM元素和组件元素的方法

文章目录 Vue获取组件元素ref获取组件元素 Vue获取组件元素 如果想使用哪个DOM元素&#xff0c;就给它加上ref属性&#xff0c;然后用$refs属性获取它的元素对象&#xff0c;示例如下&#xff1a; 全部代码&#xff1a; <!DOCTYPE html> <html><head><m…

Vue.js中$refs{}获取DOM元素

如果我们想获取DOM元素&#xff0c;一般使用js中的document.querySelector来获取这个dom节点&#xff0c;然后在获取元素的值&#xff0c;现在Vue提供给我们一种更便捷的方式来获取DOM元素-----$refs{} $refs{}----获取标签元素 说明&#xff1a;一个对象&#xff0c;持有注册…

vue中怎么获取元素

vue中怎么获取元素 在元素上添加 v-el&#xff1a;food-wrapper &#xff08;不用驼峰的写法&#xff09; vue1版本 报错&#xff1a; vue2版本 &#xff08;vue2把vue1中的 v-el 改为了 ref vue1 v-el:foods-wrapper 调用的时候 this. el.foodsWrappervue2ref:foods−wrapp…

vue怎么点击获取当前元素

vue中有两种方法获取到当前元素 var el event.target; //当前元素&#xff0c;可修改&#xff08;能够用此方法获取到他的子元素&#xff0c;不能获取他本身的内容&#xff09; var el event.currentTarget;//当前元素&#xff0c;不可修改&#xff08;能够用此方法获取到他的…

vue3获取dom

在vue3中获取dom&#xff0c;有几点需要注意&#xff1a; 1&#xff0c;获取dom的ref元素名称&#xff0c;要对应暴露的名称&#xff0c;不然会出现无效的dom报错&#xff0c;也就是拿到的是null 2,在setup中&#xff0c;使用ref&#xff08;null&#xff09;获取dom 3,不能…

vue3中获取dom元素和操作

一&#xff0c;需求概述 直接举例子来说明吧&#xff0c;我想要做的是&#xff0c;遍历这几个菜单&#xff0c;获取他们的dom元素的宽度。当文字dom元素宽度太长的话&#xff0c;需要滚动显示文本。 二&#xff0c;实现思路 对应的html: <div class"icon-box"…

vue 3.0 使用ref获取dom元素

前言 附上vue3.0文档&#xff1a;Vue3中文文档 - vuejs 2022.10.22 更新 鉴于较多人询问几个高频问题&#xff0c;在此做统一回复 ref.value获取到的是null 答&#xff1a;检查是否将ref变量return出去了 答&#xff1a;检查是在哪里进行的console.log&#xff0c;setup函数…

Vue.js实例学习:获取DOM元素

一、获取DOM元素 在Vue中获取DOM元素&#xff0c;我们可以用ref。 用法(和React一样)&#xff1a; &#xff08;1&#xff09;在组件的DOM部分&#xff0c;任意标签中 写上&#xff1a;ref"xxx" &#xff08;2&#xff09;通过组件对象 this.$refs.xxx 获取到元素 …

ref 引用(vue获取DOM元素)

ref 引用 jquery 牛逼 简化了程序员操作DOM的过程 vue 优势&#xff1a; MVVM 在 vue 中&#xff0c;程序员不需要操作DOM。只需要把数据维护好&#xff01;(数据驱动视图) 结论&#xff1a;在 vue 项目&#xff0c;强烈不建议大家安装和使用jQuery&#xff01;&#xff01;&am…

sql中批量插入数据用法

单次插入数据方法 INSERT INTO 表名&#xff08;字段1&#xff0c;字段2&#xff0c;字段3&#xff09;VALUES(第一个值&#xff0c;第二个值&#xff0c;第三个值&#xff09; 多次插入方法 第一种 INSERT INTO 表名&#xff08;字段1&#xff0c;字段2&#xff0c;字段3…

sql-批量插入数据脚本

批量插入数据脚本 1、第一种批量插入数据脚本. 可以基本满足要求。理解上较为简单&#xff0c;所以这个最常用。 DECLAREmaxnumber CONSTANT INT : 5000;--插入5000条数据i INT : 1;--i的取值从1开始 BEGINFOR i IN 1 .. maxnumber loopinsert into ODS.TABLE1--表名(ID, P_ID…

oracle11g批量insert多条,Oracle高效批量插入数据

一、准备工作 建表 CREATE TABLE TEMP_20200210 ( DMC VARCHAR2(100); ) 用程序拼接如下的批量插入的SQL INSERT INTO TEMP_20200210 (DMC) SELECT CD.* FROM ( SELECT 1234567 FROM DUAL UNION SELECT 1234568 FROM DUAL UNION SELECT 1234568 FROM DUAL ) CD 在C盘文件夹下放…

springboot 注解方式批量插入数据

文章目录 一.使用场景二.实现方法1.mysql表结构2.domain3.mapper4.测试类5.测试结果 三.插入效率对比1.批量插入2.一条一条插入 一.使用场景 一次请求需要往数据库插入多条数据时&#xff0c;可以节省大量时间&#xff0c;mysql操作在连接和断开时的开销超过本次操作总开销的4…