Maison développement back-end tutoriel php 用nginx+uwsgi+redis实现游戏GM聊天功能

用nginx+uwsgi+redis实现游戏GM聊天功能

Aug 08, 2016 am 09:19 AM
msg return

原始需求

一个客服GM能够加所有游戏服内的玩家为好友,并能进行聊天。具体功能如下:
* GM上、下线
* 加游戏玩家为好友
* 删游戏玩家为好友
* GM发送聊天消息
* 玩家推送聊天消息
额外限定:一个GM账号能够添加多个游戏玩家为好友,而一个游戏玩家只能被一个GM账号添加

需求分析

因为我们游戏内并没有跨服聊天、跨服好友这种功能,而且以后也不会支持,所以让GM在游戏里面创建角色,然后加各个游戏服的玩家进行聊天的方案是无法实施的。 而且GM实际上并不是一个游戏角色,也不用在游戏内创建。
整个的难点是,如何让各个游戏服访问到GM发过来的各种数据,如何将玩家的数据推送给GM。

具体实现

为了实现GM的数据在各个服务器传递,我们采用了一种简单的方案:将GM的数据放在我们的web服务器上,各个游戏服定时从web服务器去拿数据。
这种方案很简单,web服务器与游戏服不用长连接,直接用http的get和post方法就可以拿数据了。整个架构如下:

<code><span>GM1</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>运维聊天服</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>游戏web服务器</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>游戏服务器1</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>-</span><span>游戏客户端1</span><span>|</span><span>|</span><span>|</span><span>|</span><span>|</span><span>|</span><span>GM2</span><span>游戏服务器2</span><span>游戏客户端2</span></code>
Copier après la connexion

这里客服GM1和GM2都用的web界面与游戏客户端聊天。
运维聊天服存在是因为:
* GM的创建需要运维那边的审批。。
* 游戏的web服务器可以进行白名单审查,只有运维聊天服的ip可以访问游戏的web服务器
上图中只有游戏客户端与游戏服务器是采用的tcp长连接,其他都是使用http短连接来实现。
web服务器采用的是nginx,而不是nodejs。nginx方案挺成熟的,而且部署也很容易。
由于,我对python的熟悉程度比lua程度高很多,所以用了uwsgi来做代理,而不是直接用lua来写。
而数据库则采用的redis,redis设置了定时存盘了。数据格式设置可参考我之前提的文章,基本都是
gm:%d:name这种格式,key表示gmx的名字是什么,val表示名字。

实现代码

nginx和uwsgi的配置已略去。因为隐私原因,相关IP已略去,代码里面也有足够的注释,不再赘述:

<code><span>#encoding: utf-8</span><span>"""
新功能:
* GM注册
* GM上线
* GM下线
* 加游戏玩家为好友
* 删除游戏好友
* GM推聊天信息
* 玩家推聊天信息

---
消息数据格式为utf-8处理后的base64编码:游戏服和GM发过来的都是base64格式,要注意分隔符没做base64处理
GS只能用get方式推送消息,所以参数用类似于urllib quote(urlencode)进行了封装。运维客户端也用get

一个GM账号能添加多个游戏玩家为好友,而一个游戏玩家只能被一个GM账号添加

"""</span><span>from</span> config <span>import</span> *
<span>from</span> json <span>import</span> dumps, loads
<span>import</span> base64
<span>import</span> urllib
<span>import</span> urllib2
<span>import</span> copy
<span>import</span> redis


MSG_SEPARATOR = <span>","</span><span>#分割信息</span>
MAX_RECV_AMOUNT = <span>10</span><span>#每次消息10条吧</span>
MSG_MAX_LEN = <span>500</span><span>#消息不弄太长了</span>CONTENT_TYPE = [(<span>"Content-Type"</span>,<span>"text/html"</span>)]
HTTP_STATUS = {
    <span>200</span>: <span>"200 OK"</span>,
    <span>404</span>: <span>"404 Not Found"</span>,
}

GAME_SERVER_INFO_URL = <span>"http://xxxxxyyyyy"</span>ROLE_INFO_URL = <span>"http://xxyyy?uid=%s&amp;hostnum=%s"</span>red = redis.StrictRedis(host=REDIS.HOST, port=REDIS.PORT, db=REDIS.DB)

<span>#游戏服务器IP白名单</span><span>if</span><span>not</span> globals().has_key(<span>"gServerIP"</span>):
    gServerIP = {}
    res_data = urllib2.urlopen(GAME_SERVER_INFO_URL)
    res = res_data.read()
    res_list = res.split(<span>"\n"</span>)
    <span>for</span> val <span>in</span> res_list: 
        <span>if</span><span>not</span> val:
            <span>continue</span>
        _, port, ip, _  = val.split(<span>" "</span>) 
        gServerIP[ip] = port

gGMIP = {
        <span>"xxxxyyyy"</span> : <span>1</span>,
}

<span><span>def</span><span>is_gm_account_exist</span><span>(account_id)</span>:</span><span>if</span> red.get(<span>"gm_account:%s:name"</span> % account_id):
        <span>return</span><span>1</span><span>return</span><span>0</span><span><span>def</span><span>is_inter_server</span><span>(hostnum)</span>:</span><span>if</span> ( int(hostnum) &gt;= <span>1000</span> ):
        <span>return</span><span>0</span><span>return</span><span>1</span><span><span>def</span><span>check_is_int</span><span>(account_id)</span>:</span><span>try</span>:
        int(account_id)
    <span>except</span>:
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: -<span>1</span>})
    <span>return</span> ()

<span>#gm client ensures the id is unique</span><span><span>def</span><span>gm_create_account</span><span>(env, params)</span>:</span>
    account_id, account_name  = params[<span>"gm_account"</span>], urllib.unquote(params[<span>"gm_name"</span>]) 
    check_res = check_is_int(account_id)
    <span>if</span> check_res: <span>return</span> check_res
    <span>if</span> is_gm_account_exist(account_id):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>1</span>}) <span>#1 the role exists</span>
    red.set(<span>"gm_account:%s:name"</span> % account_id, account_name)
    red.sadd(<span>"gm_online_list"</span>, account_id)
    <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>})

<span>#check param</span><span><span>def</span><span>gm_add_friend</span><span>(env, params)</span>:</span>
    var = gm_account, hostnum, usernum = params[<span>"gm_account"</span>], params[<span>"host"</span>], params[<span>"uid"</span>]
    <span>for</span> num <span>in</span> var:
        check_res = check_is_int(num)
        <span>if</span> check_res: <span>return</span> check_res
    <span>if</span><span>not</span> is_gm_account_exist(gm_account):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>2</span>}) <span>#2 the role doesn't exist</span><span>if</span> ( red.get(<span>"gs_usernum:%s:friend"</span> % usernum) ):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>3</span>}) <span>#3 the usernum has gotten a friend</span><span>#内服计费没存数据,就不处理了</span><span>if</span><span>not</span> is_inter_server(hostnum):
        http_res_data = urllib2.urlopen(ROLE_INFO_URL % (usernum, hostnum))
        res = loads(http_res_data.read())
        <span>if</span> (type(res) != type({})) <span>or</span> (res.get(<span>"code"</span>, <span>0</span>) != <span>1</span>):
            <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>4</span>}) <span>#4 the uid doesn't exist</span>    red.sadd(<span>"gm_account:%s:friend"</span> % gm_account, usernum) <span>#两边都处理下</span>    red.sadd(<span>"gs_hostnum:%s"</span> % hostnum, usernum) <span>#记录该服务器的所有玩家</span>
    red.set(<span>"gs_usernum:%s:hostnum"</span> % usernum, hostnum) <span>#该玩家的信息</span>
    red.set(<span>"gs_usernum:%s:friend"</span> % usernum, gm_account) <span>#一个玩家只能被一个gm添加为好友</span>    red.sadd(<span>"apply_frd_list"</span>, usernum) <span>#usernum will be added </span>
    red.hdel(<span>"remove_frd_list"</span>, usernum) <span>#信息残留</span><span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>}) 

<span><span>def</span><span>gm_remove_friend</span><span>(env, params)</span>:</span>
    account_id, uid = params[<span>"gm_account"</span>], params[<span>"uid"</span>]
    <span>if</span><span>not</span> is_gm_account_exist(account_id):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>2</span>}) <span>#2 the role doesn't exist</span><span>if</span> red.get(<span>"gs_usernum:%s:friend"</span> % uid) != account_id:
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>5</span>})  <span># the usernum has friend but isn't the gm</span><span>if</span><span>not</span> red.srem(<span>"gm_account:%s:friend"</span> % account_id, uid):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>4</span>})  <span># the usernum is not a friend of the gm</span>    hostnum = red.get(<span>"gs_usernum:%s:hostnum"</span> % uid)
    red.delete(<span>"gs_usernum:%s:hostnum"</span> % uid) <span>#合服考虑,如果合服了GM手动删除这个玩家吧</span>
    red.srem(<span>"gs_hostnum:%s"</span> % hostnum, uid)

    red.delete(<span>"gs_usernum:%s:friend"</span> % uid) 
    red.hset(<span>"remove_frd_list"</span>, uid, hostnum) <span>#uid的信息已经丢失,先额外保存下hostnum信息</span>
    red.srem(<span>"apply_frd_list"</span>, uid) <span>#信息残留</span><span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>}) 

<span>#GM账号很少</span><span><span>def</span><span>gm_online</span><span>(env, params)</span>:</span>
    account_id = params[<span>"gm_account"</span>] <span>#可能客户端bug没发下线,直接sadd吧</span><span>if</span><span>not</span> is_gm_account_exist(account_id):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>2</span>}) <span>#2 the role doesn't exist</span>
    red.sadd(<span>"gm_online_list"</span>, account_id)
    <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>})

<span><span>def</span><span>gm_offline</span><span>(env, params)</span>:</span>
    account_id = params[<span>"gm_account"</span>]
    <span>if</span><span>not</span> red.srem(<span>"gm_online_list"</span>, account_id):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>})
    <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>})

<span>#存在usernum上,gs_msg和gm_msg</span><span><span>def</span><span>gm_sendmsg</span><span>(env, params)</span>:</span>
    account_id, uid, msg = params[<span>"gm_account"</span>], params[<span>"uid"</span>], urllib.unquote(params[<span>"msg"</span>]) <span>#只能向好友发</span><span>if</span><span>not</span> red.sismember(<span>"gm_account:%s:friend"</span> % account_id, uid):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>4</span>})  <span># the usernum is not a friend of the gm</span><span>if</span> red.get(<span>"gs_usernum:%s:friend"</span> % uid) != account_id:
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>5</span>})  <span># the usernum has friend but isn't the gm or doesn't have</span>
    red.lpush(<span>"gs_usernum:%s:msg_from_gm"</span> % uid, msg)
    red.sadd(<span>"gm_newmsg_list"</span>, uid) <span>#gs get msg from this set</span><span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>})

<span>#gm轮训所有的,他那边还有个服务器...</span><span>#{gm_account:{"uid": msg, "uid2": msg2}}</span><span><span>def</span><span>gm_receivemsg</span><span>(env, params)</span>:</span>
    user_set = copy.copy(red.smembers(<span>"gs_newmsg_list"</span>))
    msg_data = {}
    <span>for</span> uid <span>in</span> user_set:
        gm_account = red.get(<span>"gs_usernum:%s:friend"</span> % uid)
        <span>if</span><span>not</span> gm_account: <span>#理论上是不会</span><span>continue</span>
        msg_list = pop_msg(uid, <span>"msg_from_gs"</span>)
        send_msg = MSG_SEPARATOR.join(msg_list)
        <span>if</span><span>not</span> send_msg:
            <span>continue</span><span>if</span><span>not</span> gm_account <span>in</span> msg_data:
            msg_data[gm_account] = []
        msg_data[gm_account].append({<span>"uid"</span> : uid, <span>"msg"</span> : send_msg})
        <span>#red.srem("gs_newmsg_list", uid)</span><span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>, <span>"data"</span>: base64.b64encode(dumps(msg_data))})

<span><span>def</span><span>pop_msg</span><span>(uid, msg_type)</span>:</span>
    msg_list = []
    msg_key = <span>"gs_usernum:%s:%s"</span> % (uid, msg_type)
    msg_len = min(MAX_RECV_AMOUNT, red.llen(msg_key))
    <span>for</span> i <span>in</span> xrange(msg_len):
        piece_msg = red.rpop(msg_key)
        msg_list.append(piece_msg)
    <span>return</span> msg_list

<span>#---------------------GS----------------------</span><span>#apply and remove</span><span><span>def</span><span>get_frd_relation</span><span>(env, params)</span>:</span>
    host = params[<span>"host"</span>]

    apply_user_set = copy.copy(red.smembers(<span>"apply_frd_list"</span>))
    apply_data = {}  <span>#{"res":1 "data":base64({uid: gm_account})}</span><span>for</span> uid <span>in</span> apply_user_set:
        hostnum = red.get(<span>"gs_usernum:%s:hostnum"</span> % uid)
        <span>if</span> hostnum != host:
            <span>continue</span>
        account_id = red.get(<span>"gs_usernum:%s:friend"</span> % uid)
        <span>if</span><span>not</span> account_id: <span>#error </span><span>continue</span>        apply_data[uid] = [account_id, red.get(<span>"gm_account:%s:name"</span> % account_id)]
        red.srem(<span>"apply_frd_list"</span>, uid)


    del_user_list = red.hkeys(<span>"remove_frd_list"</span>)
    remove_list = []
    <span>for</span> uid <span>in</span> del_user_list:
        hostnum = red.hget(<span>"remove_frd_list"</span>, uid)
        <span>if</span> hostnum != host:
            <span>continue</span>
        remove_list.append(uid)
        red.hdel(<span>"remove_frd_list"</span>, uid)
    <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>, <span>"apply_data"</span>: base64.b64encode(dumps(apply_data)), <span>"remove_data"</span>: base64.b64encode(dumps(remove_list))})   

<span><span>def</span><span>gs_sendmsg</span><span>(env, params)</span>:</span>
    uid, msg = params[<span>"uid"</span>], urllib.unquote(params[<span>"msg"</span>])
    <span>if</span><span>not</span> red.get(<span>"gs_usernum:%s:friend"</span> % uid):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>0</span>, <span>"errno"</span>: <span>5</span>})  <span># the usernum has friend but isn't the gm or doesn't have</span>
    red.lpush(<span>"gs_usernum:%s:msg_from_gs"</span> % uid, msg)
    red.sadd(<span>"gs_newmsg_list"</span>, uid) <span>#gm get msg from this set</span><span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>})

<span><span>def</span><span>gs_receivemsg</span><span>(env, params)</span>:</span>
    host = params[<span>"host"</span>]
    user_set = copy.copy(red.smembers(<span>"gm_newmsg_list"</span>))
    total_msg_list = [] 
    <span>for</span> uid <span>in</span> user_set:
        hostnum = red.get(<span>"gs_usernum:%s:hostnum"</span> % uid)
        <span>if</span> hostnum != host:
            <span>continue</span>
        msg_list = pop_msg(uid, <span>"msg_from_gm"</span>)
        user_msg = MSG_SEPARATOR.join(msg_list)
        <span>if</span><span>not</span> user_msg:
            <span>continue</span>
        msg_data = {
                <span>"uid"</span>   : uid,
                <span>"msg"</span>   : user_msg,
        }
        total_msg_list.append(msg_data)
    <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>, <span>"data"</span>: base64.b64encode(dumps(total_msg_list))})

<span><span>def</span><span>get_online_list</span><span>(env, params)</span>:</span>
    host = params[<span>"host"</span>]
    send_list = []
    online_list = red.smembers(<span>"gm_online_list"</span>)
    <span>for</span> account_id <span>in</span> online_list:
        frd_set = red.smembers(<span>"gm_account:%s:friend"</span> % account_id)
        <span>for</span> uid <span>in</span> frd_set:
            <span>if</span> red.get(<span>"gs_usernum:%s:hostnum"</span> % uid) == host:
                send_list.append(account_id) <span>#只有这个服务器有gm的好友,才通知</span><span>break</span><span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, dumps({<span>"res"</span>: <span>1</span>, <span>"data"</span>: base64.b64encode(dumps(send_list))})

<span>#get:  action=create&amp;gm_account&amp;gm_name  创建账号</span><span>#get:  action=add&amp;gm_account&amp;host&amp;uid 添加好友</span><span>#get:  action=del&amp;gm_account&amp;uid 删除好友</span><span>#get:  action=online&amp;gm_account上线</span><span>#get:  action=offline&amp;gm_account 下线</span><span>#get:  action=send&amp;gm_account&amp;uid&amp;msg 发送消息</span><span>#get:  action=receive 轮训消息</span>
GM_FUNC = {
        <span>"create"</span>    : gm_create_account,
        <span>"add"</span>       : gm_add_friend,
        <span>"del"</span>       : gm_remove_friend,
        <span>"online"</span>    : gm_online,
        <span>"offline"</span>   : gm_offline,
        <span>"send"</span>      : gm_sendmsg,
        <span>"receive"</span>   : gm_receivemsg,
}

<span><span>def</span><span>handle_gm_ticket</span><span>(env, params)</span>:</span><span>if</span><span>not</span> gGMIP.get(env[<span>"REMOTE_ADDR"</span>], <span>0</span>):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, <span>"%s has no access to the website"</span> % env[<span>"REMOTE_ADDR"</span>]
    func = GM_FUNC.get(params[<span>"action"</span>], <span>None</span>)
    <span>if</span><span>not</span> func:
        <span>return</span> HTTP_STATUS[<span>404</span>], CONTENT_TYPE, <span>"err action %s"</span> % params[<span>"action"</span>]
    <span>return</span> func(env, params)

<span>#get    action=relation&amp;host</span><span>#get    action=send&amp;uid&amp;msg</span><span>#get    action=receive&amp;host</span><span>#get    action=online&amp;host        </span>
GS_FUNC = { 
        <span>"relation"</span>  : get_frd_relation,
        <span>"send"</span>      : gs_sendmsg,
        <span>"receive"</span>   : gs_receivemsg,
        <span>"online"</span>    : get_online_list,
}

<span><span>def</span><span>handle_gs_ticket</span><span>(env, params)</span>:</span><span>if</span><span>not</span> gServerIP.get(env[<span>"REMOTE_ADDR"</span>], <span>0</span>):
        <span>return</span> HTTP_STATUS[<span>200</span>], CONTENT_TYPE, <span>"%s has no access to the website"</span> % env[<span>"REMOTE_ADDR"</span>]
    func = GS_FUNC.get(params[<span>"action"</span>], <span>None</span>)
    <span>if</span><span>not</span> func:
        <span>return</span> HTTP_STATUS[<span>404</span>], CONTENT_TYPE, <span>"err action %s"</span> % params[<span>"action"</span>]
    <span>return</span> func(env, params)

</code>
Copier après la connexion

版权声明:本文为博主原创文章,未经博主允许不得转载。

以上就介绍了用nginx+uwsgi+redis实现游戏GM聊天功能,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Article chaud

Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Article chaud

Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Explication détaillée de l'utilisation de return en langage C Explication détaillée de l'utilisation de return en langage C Oct 07, 2023 am 10:58 AM

Explication détaillée de l'utilisation de return en langage C

Quel est l'ordre d'exécution des instructions return et enfin en Java ? Quel est l'ordre d'exécution des instructions return et enfin en Java ? Apr 25, 2023 pm 07:55 PM

Quel est l'ordre d'exécution des instructions return et enfin en Java ?

Dans quelle devise est le MSG ? La pièce MSG vaut-elle la peine d'investir ? Dans quelle devise est le MSG ? La pièce MSG vaut-elle la peine d'investir ? Feb 21, 2024 pm 05:28 PM

Dans quelle devise est le MSG ? La pièce MSG vaut-elle la peine d'investir ?

Explication détaillée des valeurs de retour de la fonction JavaScript et des instructions de retour Explication détaillée des valeurs de retour de la fonction JavaScript et des instructions de retour Aug 04, 2022 am 09:46 AM

Explication détaillée des valeurs de retour de la fonction JavaScript et des instructions de retour

Comment utiliser la valeur de retour en Python Comment utiliser la valeur de retour en Python Oct 07, 2023 am 11:10 AM

Comment utiliser la valeur de retour en Python

Comment Vue3 utilise-t-il le sucre syntaxique de configuration pour refuser d'écrire le retour Comment Vue3 utilise-t-il le sucre syntaxique de configuration pour refuser d'écrire le retour May 12, 2023 pm 06:34 PM

Comment Vue3 utilise-t-il le sucre syntaxique de configuration pour refuser d'écrire le retour

Utilisez le mot-clé return en JavaScript Utilisez le mot-clé return en JavaScript Feb 18, 2024 pm 12:45 PM

Utilisez le mot-clé return en JavaScript

En Java, une fois l'instruction return dans une méthode exécutée, le bloc final sera-t-il exécuté ? En Java, une fois l'instruction return dans une méthode exécutée, le bloc final sera-t-il exécuté ? Sep 17, 2023 pm 03:05 PM

En Java, une fois l'instruction return dans une méthode exécutée, le bloc final sera-t-il exécuté ?

See all articles