ET消息傳輸流程

ET消息傳輸流程

結(jié)構(gòu)模型

  • NetworkComponent【NetOuterComponent、NetInnerComponent】
    • Session
    • AService【KService、TService胳赌、WService】
      • Socket
      • PacketParser
      • CircularBuffer
      • AChannel【KChannel、TChannel昵慌、WChannel】
    • IMessagePacker【MongoPacker盐茎、ProtobufPacker】
    • IMessageDispatcher【InnerMessageDispatcher、OuterMessageDispatcher(服務(wù)端)日矫、OuterMessageDispatcher(客戶端)】
  • OpcodeTypeComponent
  • MessageDispatcherComponent
    • IMHandler【AMHandler、AMRpcHandler】

服務(wù)器獨(dú)占

  • MailboxDispatcherComponent
    • IMailboxHandler【MailboxGateSessionHandler绑榴、MailboxMessageDispatcherHandler】
  • ActorMessageDispatcherComponent
    • IMActorHandler【AMActorHandler哪轿、AMActorRpcHandler、AMActorLocationHandler翔怎、AMActorLocationRpcHandler】
  • LocationProxyComponent
  • LocationComponent
  • ActorMessageSenderComponent
    • ActorMessageSender
  • ActorLocationSenderComponent
    • ActorLocationSender

客戶端建立Session

  1. 添加NetOuterComponent

    因?yàn)?code>NetOuterComponent外網(wǎng)組件繼承自NetworkComponent網(wǎng)絡(luò)組件窃诉,所以在Init類中為Scene添加NetOuterComponent也就等于添加了NetworkComponent杨耙,同時(shí)NetOuterComponent還指定了網(wǎng)絡(luò)組件以什么協(xié)議溝通;

    • 考慮到服務(wù)端Hotfix與Model分離規(guī)則飘痛,所以NetOuterComponent的事件驅(qū)動(dòng)與組件不在一個(gè)類中珊膜。
    • NetOuterComponentAwake事件中創(chuàng)建了TService、ProtobufPacker宣脉、OuterMessageDispatcher车柠,并保存引用到自身
      • TService:TCPService,繼承自AService
      • ProtobufPacker:Protobuf打包器塑猖,繼承自IMessagePacker,主要用于調(diào)用ProtobufHelper對(duì)消息進(jìn)行打包處理
      • OuterMessageDispatcher:外部消息分發(fā)組件竹祷,繼承自IMessageDispatcher,主要用于調(diào)用MessageDispatcherComponent對(duì)外部消息進(jìn)行分發(fā)處理
  2. 創(chuàng)建Model.Session

    通過外網(wǎng)組件間接調(diào)用網(wǎng)絡(luò)組件的Create方法羊苟,先通過TServiceConnectChannel方法傳入遠(yuǎn)端IP地址創(chuàng)建了一個(gè)TChannel,然后將TChannel作物初始化參數(shù)創(chuàng)建了一個(gè)Model.Session塑陵,并調(diào)用SessionStart方法啟動(dòng)Session。

    • TChannel:TCP通道蜡励,繼承自:AChannel猿妈,在構(gòu)造函數(shù)中創(chuàng)建了Socket、PacketParser巍虫,并設(shè)置了各種流處理相關(guān)屬性

      • Socket:套接字
      • PacketParser:包解析器
      • CircularBuffer:緩沖區(qū)
    • Session

      在其Awake方法中彭则,將NetworkComponent.Remove自身方法作為委托傳入了TChannelErrorCallback中,還將自身的OnRead方法作為委托傳入了TChannelReadCallback

      Session的Start方法調(diào)用了TChannelStart方法

      1. 建立遠(yuǎn)程鏈接

      2. 開始循環(huán)異步接收消息

        注意占遥,到這里Model.Session已經(jīng)創(chuàng)建完成俯抖,并且開始接收消息,以下是收到消息后的處理

        • 當(dāng)一條消息讀取完畢后瓦胎,先調(diào)用PacketParser包解析器芬萍,進(jìn)行解包
        • 再通過委托調(diào)用SessionOnRead方法對(duì)消息進(jìn)行分發(fā)處理
  3. 創(chuàng)建Hotfix.Session

    將上一步生成的Model.Session作為初始化參數(shù),創(chuàng)建一個(gè)Hotfix.Session搔啊,該類的Dispose方法會(huì)自動(dòng)調(diào)用Model.SessionDispose

    在該類的Awake事件中柬祠,會(huì)給Model.Session添加SessionCallbackComponent熱更層Session回調(diào)組件;該組件持有兩個(gè)委托

    • MessageCallback用于Model.Session通過委托調(diào)用Hotfix.SessionRun方法
    • DisposeCallback用于Model.Session通過委托調(diào)用Hotfix.SessionDispose方法

發(fā)送消息

  1. Hotfix.Session

    • 發(fā)送消息

      • 發(fā)送普通消息负芋,調(diào)用Hotfix.SessionSend方法

      • 發(fā)送請(qǐng)求消息漫蛔,調(diào)用Hotfix.SessionCall方法,創(chuàng)建一個(gè)異步完成的委托回調(diào)旧蛾,用于消息答復(fù)時(shí)觸發(fā)ETTask返回

    • 通過OpcodeTypeComponent對(duì)應(yīng)的消息碼

    • 調(diào)用Model.SessionSend方法

  2. Model.Session

    • 通過NetOuterComponent類的ProtobufPacker序列化消息
    • 寫入操作碼
    • 調(diào)用TChannelSend方法
  3. Tchannel

    • 將消息寫入緩沖區(qū)CircularBuffer
    • 通過TServiceMarkNeedStartSend方法將自生標(biāo)記為待發(fā)送
    • TServiceUpdate事件將調(diào)用TchannelStartSend方法發(fā)送消息
    • StartSend調(diào)用SendAsync向遠(yuǎn)端發(fā)送一條消息

接收消息

TChannelStart方法將開啟循環(huán)接收消息莽龟。下面演示接收到一條消息后的處理流程

  1. TChannel

    • 當(dāng)一條消息讀取完畢后,先調(diào)用PacketParser包解析器锨天,進(jìn)行解包
    • 通過委托調(diào)用SessionOnRead方法對(duì)消息進(jìn)行分發(fā)處理
  2. Session

    • 獲取操作碼

    • 通過OpcodeHelper.IsClientHotfixMessage檢測(cè)是否是熱更層消息

      如果是熱更層消息毯盈,則通過SessionCallbackComponent委托調(diào)用熱更層Session處理消息,后續(xù)hotfix和Model處理流程是一樣的

    • 通過OpcodeTypeComponent操作碼-類型組件獲取操作碼對(duì)應(yīng)的消息類實(shí)例

    • 通過NetOuterComponent類的ProtobufPacker反序列化數(shù)據(jù)

    • 檢測(cè)消息是否是響應(yīng)消息

      • 不是響應(yīng)消息病袄,直接通過NetOuterComponent類的OuterMessageDispatcher調(diào)用MessageDispatcherComponent處理消息
      • 是響應(yīng)消息搂赋,通過消息的RpcId查找請(qǐng)求隊(duì)列中對(duì)應(yīng)的請(qǐng)求赘阀,并激活完成事件

服務(wù)端Actor模型建立

  • 登錄服務(wù)器

    1. 添加NetInnerComponent、NetOuterComponent內(nèi)網(wǎng)組件和外網(wǎng)組件來為當(dāng)前服務(wù)器建立基本網(wǎng)絡(luò)收發(fā)配置
    2. 分配服務(wù)器網(wǎng)關(guān)地址脑奠,在登錄驗(yàn)證通過后基公,通過RealmGateAddressComponent隨機(jī)網(wǎng)關(guān)地址組件獲取內(nèi)網(wǎng)網(wǎng)關(guān)地址
    3. 通過向NetInnerComponent.Get方法傳入獲取到的網(wǎng)關(guān)地址,創(chuàng)建一個(gè)與網(wǎng)關(guān)服務(wù)器鏈接的內(nèi)網(wǎng)Session
    4. 通過Session在網(wǎng)關(guān)服務(wù)器上創(chuàng)建一個(gè)登錄Key捺信,然后將Key和客戶端地址保存到GateSessionKeyComponent網(wǎng)關(guān)登錄Key組件中,注意:該Key會(huì)在20秒后自動(dòng)銷毀
  • 網(wǎng)關(guān)服務(wù)器

    1. 客戶端通過從登錄服務(wù)器獲取的外網(wǎng)網(wǎng)關(guān)地址欠痴,建立一個(gè)鏈接網(wǎng)關(guān)的Session

    2. 通過GateSessionKeyComponent驗(yàn)證網(wǎng)關(guān)登錄Key和Value是否匹配迄靠,不匹配返回登錄失敗

    3. 將Value作為初始參數(shù)創(chuàng)建一個(gè)Plyaer

    4. 為當(dāng)前鏈接客戶端的Session添加SessionPlayerComponentSession綁定Player組件,并綁定Player

      該類在Session銷毀時(shí)喇辽,自身的Destroy事件會(huì)被調(diào)用掌挚。這里的Destroy還沒寫完

    5. 同時(shí)為當(dāng)前Session添加郵箱組件,并設(shè)置類型為網(wǎng)關(guān)郵箱(網(wǎng)關(guān)郵箱收到的信息會(huì)直接轉(zhuǎn)發(fā)給鏈接當(dāng)前Session的客戶端)

      掛上這個(gè)組件表示該Entity是一個(gè)Actor,接收的消息將會(huì)隊(duì)列處理

      到這一步菩咨,算是為對(duì)象建立Actor模型完成

    6. 進(jìn)入Map服務(wù)器

      通過StartConfigComponent初始配置管理組件獲取一個(gè)map服務(wù)器內(nèi)網(wǎng)地址吠式,并根據(jù)地址使用NetInnerComponent.Get方法創(chuàng)建一個(gè)鏈接Map服務(wù)器的內(nèi)網(wǎng)Session

      通過Session發(fā)送在Map服務(wù)器上創(chuàng)建Unit的請(qǐng)求,并傳入當(dāng)前網(wǎng)關(guān)服務(wù)鏈接客戶端的Session的唯一Id

  • Map服務(wù)器

    1. 創(chuàng)建Unit

    2. 為Unit添加UnitGateComponentUnit網(wǎng)關(guān)組件抽米,并將傳入的網(wǎng)關(guān)Session的唯一Id綁定到組件中

    3. 為Unit添加MailBoxComponent郵箱組件

    4. 調(diào)用MailBoxComponent郵箱組件的AddLocation方法

      調(diào)用LocationProxyComponent位置代理組件的Add方法

      創(chuàng)建一獲取地址服務(wù)器的內(nèi)網(wǎng)地址創(chuàng)建一個(gè)鏈接地址服務(wù)器的內(nèi)網(wǎng)Session

      通過內(nèi)網(wǎng)Session將Unit的Id和唯一Id發(fā)動(dòng)到Location服務(wù)器

  • Location服務(wù)器

    1. 接收到Map服務(wù)器發(fā)送的ObjectAddRequest請(qǐng)求后特占,在LocationComponent位置組件中保存?zhèn)魉瓦^來的Unit的Id與InstanceId

      到這一步,算是為對(duì)象建立了LocationActor模型完成云茸,其實(shí)Actor模型和LocationActor模型代碼上步驟分支主要在于添加郵箱組件時(shí)分配的郵箱類型和有沒有調(diào)用AddLocation方法

發(fā)送Actor消息

參考服務(wù)端MessageHelper(客戶端ActorLocation消息參考OperaComponent是目,服務(wù)端參考SessionPlayerComponentSystem

  1. 獲取Unit的UnitGateComponentUnit網(wǎng)關(guān)組件,并得到組件中網(wǎng)關(guān)Session對(duì)象的唯一Id

  2. 通過網(wǎng)關(guān)Session的唯一Id提取網(wǎng)關(guān)服務(wù)器設(shè)備Id

  3. 通過ActorMessageSenderComponentActor消息發(fā)送器管理組件創(chuàng)建一個(gè)ActorMessageSenderActor消息發(fā)送器标捺,并通過上一步獲取的網(wǎng)關(guān)服務(wù)器設(shè)備Id查找到對(duì)應(yīng)的網(wǎng)關(guān)服務(wù)器的內(nèi)網(wǎng)地址懊纳,賦值到Actor消息發(fā)送器中。

  4. 調(diào)用Actor消息發(fā)送器的Send方法

    使用NetInnerComponent內(nèi)網(wǎng)組件和網(wǎng)關(guān)服務(wù)器地址亡容,創(chuàng)建一個(gè)鏈接網(wǎng)關(guān)服務(wù)器的內(nèi)網(wǎng)Session嗤疯,然后使用該Session發(fā)送消息。

    由于創(chuàng)建Session時(shí)使用的時(shí)內(nèi)網(wǎng)地址闺兢,所以會(huì)有網(wǎng)關(guān)服務(wù)器的內(nèi)網(wǎng)組件接收Session傳來的消息茂缚,由于內(nèi)網(wǎng)組件使用的消息分發(fā)器和外網(wǎng)組件不同,所以在解析消息的時(shí)候Actor消息和普通消息相比會(huì)有更多步驟

接收Actor消息

和普通消息前期收取規(guī)則是一樣的屋谭,產(chǎn)生差異在于Session調(diào)用消息分發(fā)器分發(fā)消息時(shí)阱佛。

  • InnerMessageDispatcher內(nèi)網(wǎng)消息分發(fā)

    1. 解析消息是否是Actor消息,非Actor消息調(diào)用MessageDispatcherComponent消息分發(fā)組件處理消息

    2. Actor消息會(huì)通過EventSystem查找發(fā)送過來的ActorID(也就是對(duì)象的InstanceId)對(duì)應(yīng)對(duì)象是否存在戴而,不存在則直接返回獲取Actor失敗異常

    3. 獲取對(duì)象身上的MailBoxComponent郵箱組件凑术,(如果獲取不到則返回獲取郵箱失敗異常)將Session和Actor消息封裝成ActorMessageInfo存入郵箱組件中

    4. 郵箱組件會(huì)在循環(huán)中讀取消息并調(diào)用MailboxDispatcherComponent郵箱分發(fā)組件的Handle方法進(jìn)行二次分發(fā)消息

    5. Handle方法根據(jù)前面的郵箱組件類型分發(fā)給MailboxGateSessionHandler或MailboxMessageDispatcherHandlerHandle方法做處理

      • MailboxGateSessionHandler直接將第三步獲取的對(duì)象轉(zhuǎn)換成Session向客戶端發(fā)送消息

      • MailboxMessageDispatcherHandler通過ActorMessageDispatcherComponentActor消息分發(fā)組件的Handle方法,將消息進(jìn)行最終分發(fā)處理

        ActorMessageDispatcherComponentHandle方法會(huì)查找注冊(cè)在組件中消息操作碼對(duì)應(yīng)的消息處理實(shí)例所意,有該實(shí)例完成消息最終的處理

  • OuterMessageDispatcher外網(wǎng)消息分發(fā)

    1. 解析消息是否是ActorLocation消息淮逊,非ActorLocation消息調(diào)用MessageDispatcherComponent消息分發(fā)組件處理消息

    2. ActorLocation消息通過Session綁定的SessionPlayerCompoennt組件獲取Player催首,再通過Player獲取UnitId;

    3. 通過ActorLocationSenderComponentActorLocation消息發(fā)送器管理組件創(chuàng)建ActorLocationSenderActorLocation消息發(fā)送器泄鹏,指定該對(duì)象的Id為UnitId郎任,并將UnitId作為Key和ActorLocation消息發(fā)送器一起保存到字典中

      由于可能產(chǎn)生Bug或者進(jìn)程掛掉而導(dǎo)致ActorLocationSender沒有返回,所以在ActorLocationSenderComponent的Start事件中開啟了一個(gè)攜程备籽,用于清理超時(shí)1分鐘沒有返回的ActorLocation消息發(fā)送器

      由于對(duì)象可能進(jìn)行跨服轉(zhuǎn)移舶治,所以消息的接收不能直接使用對(duì)象身上掛在組件,需要生成一個(gè)代理對(duì)象來收發(fā)消息车猬、對(duì)消息進(jìn)行阻塞霉猛,也就是ActorLocationSender

      • ActorLocationSender的Start事件中,通過向LocationProxyComponent位置代理組件傳入U(xiǎn)nitId調(diào)用Get方法獲取唯一ID
      • Get方法中建立一個(gè)鏈接位置服務(wù)器的內(nèi)網(wǎng)Session珠闰,并通過該Session發(fā)送ObjectGetResponse請(qǐng)求惜浅,傳入U(xiǎn)nitID
      • 在位置服務(wù)器中,通過接收到的UnitId向LocationComponent位置組件GetAsync異步獲取方法獲取Unit的唯一Id
      • ActorLocationSender的Start事件中伏嗜,還開啟了一個(gè)攜程循環(huán)坛悉,用于讀取ActorTask隊(duì)列
    4. 調(diào)用ActorLocationSenderActorLocation消息發(fā)送器的Call或Send方法,創(chuàng)建一個(gè)ActorTaskActor消息任務(wù)承绸,并保存到隊(duì)列中

    5. ActorLocationSenderActorLocation消息發(fā)送器的UpdateAsync方法中裸影,會(huì)循環(huán)讀取隊(duì)列中的ActoTaskActor消息任務(wù),并調(diào)用RunTask方法發(fā)送消息

      RunTask方法流程

      1. 先通過ActorMessageSenderComponentActor消息發(fā)送器管理組件的Get方法獲取一個(gè)ActorMessageSenderActor消息發(fā)送器
      • Get方法會(huì)使用傳入的Unit的唯一ID提取對(duì)應(yīng)的服務(wù)器設(shè)備ID军熏,再通過設(shè)備ID獲取對(duì)應(yīng)服務(wù)器內(nèi)網(wǎng)地址
        • 將Unit唯一ID和服務(wù)器地址作為初始參數(shù)創(chuàng)建一個(gè)ActorMessageSenderActor消息發(fā)送器
      1. 使用ActorMessageSender.CallWithoutException不拋出異常的方式發(fā)送消息空民,這里后續(xù)邏輯就接入了前面所說的InnerMessageDispatcher內(nèi)網(wǎng)消息分發(fā)

      2. 檢測(cè)上一步消息是否發(fā)送成功

        • 如果發(fā)送成功,則完成ActorLocation消息的收發(fā)流程

        • 如果是獲取Actor失敗異常羞迷,則等待半秒界轩,然后重新從上面第五步開始UpdateAsync方法開始執(zhí)行,注意該流程會(huì)重復(fù)5次衔瓮,超過五次會(huì)將ActorLocationSender自身銷毀浊猾,并拋出異常

        • 如果是獲取郵箱失敗異常,則直接將自身銷毀热鞍,并拋出異常

對(duì)象跨服跳轉(zhuǎn)

參考Actor_TransferHandler

  • Map服務(wù)器A

    1. 調(diào)用LocationProxyComponent位置代理組件的Lock方法(傳入上鎖對(duì)象ID和上鎖時(shí)長(zhǎng))葫慎,建立與位置服務(wù)器鏈接的內(nèi)網(wǎng)Session,并發(fā)送上鎖消息ObjectLockRequest
  • Location服務(wù)器

    1. 調(diào)用LocationComponentLock方法薇宠,在Lock方法中會(huì)將上鎖對(duì)象ID和唯一ID保存到容器中偷办,建立一個(gè)計(jì)時(shí)器,超時(shí)后從容器中去除對(duì)象
  • Map服務(wù)器A

    1. EventSystem中刪除對(duì)象澄港,保存對(duì)象原有唯一ID
    2. 通過轉(zhuǎn)移的目標(biāo)服務(wù)器設(shè)備ID獲取目標(biāo)服務(wù)器地址椒涯,并建立內(nèi)網(wǎng)Session
    3. 通過內(nèi)網(wǎng)Session,向目標(biāo)服務(wù)器發(fā)送轉(zhuǎn)移對(duì)象回梧。
  • Map服務(wù)器B

    1. 將收到的對(duì)象反序列化(注意這里反序列化會(huì)重新生成對(duì)象的唯一ID)
    2. 將對(duì)象加入EventSystem事件系統(tǒng)中
    3. 重新添加MailBoxComponent郵箱組件废岂,來構(gòu)建Actor模型
    4. 返回給服務(wù)器A新的唯一ID
  • Map服務(wù)器A

    1. 將對(duì)象銷毀
    2. 調(diào)用LocationProxyComponent位置代理組件的UnLock方法(傳入上鎖對(duì)象ID和新的唯一ID)祖搓,建立與位置服務(wù)器鏈接的內(nèi)網(wǎng)Session,并發(fā)送上鎖消息ObjectUnLockRequest
  • Location服務(wù)器

    1. 調(diào)用LocationComponentUnLockAndUpdate方法
    2. 在UnLockAndUpdate方法中會(huì)將上鎖對(duì)象的唯一ID進(jìn)行更新
    3. 調(diào)用UnLock方法湖苞,從上鎖容器中刪除對(duì)象拯欧,然后將上鎖期間收到堵塞的Location消息重新進(jìn)行發(fā)送

總結(jié)

消息分類:

  • S2C:

    • IMessage
    • IRequest
  • C2S:

    • IMessage

    • IRequest

    • IActorLocationMessage

      前提是服務(wù)端對(duì)鏈接客戶端的Session綁定的對(duì)象進(jìn)行了ActorLocation綁定處理(掛載了郵箱組件,并注冊(cè)到位置服務(wù)器中)财骨,使用Session按正常方式發(fā)送消息即可

    • IActorLocationRequest

  • S2S:

    • IMessage

    • IRequest

    • IActorMessage

      前提是知道接收對(duì)象的唯一ID镐作,且接收對(duì)象掛在了郵箱組件

      通過ActorMessageSenderComponent組件傳入對(duì)象的唯一ID,建立ActorMessageSender隆箩,通過ActorMessageSender發(fā)送消息

      由于Actor是走內(nèi)網(wǎng)組件所以只能在服務(wù)器內(nèi)部傳輸使用该贾,如果希望外網(wǎng)也能調(diào)用,需要自己手動(dòng)擴(kuò)展OuterMessageDispatcher

    • IActorRequest

    • IActorLocationMessage

      前提是接收對(duì)象有綁定郵箱組件摘仅,并在地址服務(wù)中進(jìn)行了注冊(cè)靶庙。

      使用ActorLocationSenderComponent組件傳入對(duì)象Id问畅,獲取ActorLocationSender娃属,通過ActorLocationSender發(fā)送消息

    • IActorLocationRequest

登錄流程:

  1. Client建立一個(gè)鏈接Realm的Session
  2. Client向Realm發(fā)送登錄請(qǐng)求,驗(yàn)證登錄賬成功后
  3. Realm向Gate獲取登錄Gate的key和Gate的地址
  4. Realm返回給Client登錄Gate的key和Gate的地址
  5. Client通過Gate地址建立一個(gè)新的Session护姆,并銷毀之前的Session
  6. Client向Gate發(fā)送登錄Gate請(qǐng)求矾端,驗(yàn)證之前返回Key成功后在Gate創(chuàng)建Player
    1. 將Client地址保存到Player中,方便后續(xù)對(duì)Client建立Session
    2. 給當(dāng)前Gate鏈接Client的Session添加郵箱組件卵皂,將Session注冊(cè)成Actor
  7. Gate返回給Client Player的ID秩铆,在客戶端建立Player
  8. Client向Gate發(fā)送登錄Map請(qǐng)求
  9. Gate向Map發(fā)送創(chuàng)建Unit請(qǐng)求
  10. Map創(chuàng)建Unit,并返回UnitId
    1. 給Unit添加郵箱組件灯变,注冊(cè)成Actor
    2. 再調(diào)用郵箱組件的AddLocation方法殴玛,將Unit注冊(cè)到Location服務(wù)器中
  11. Gate返回給Client在Map返回的UnitId
  12. Client通過UnitId建立Unit
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市添祸,隨后出現(xiàn)的幾起案子滚粟,更是在濱河造成了極大的恐慌,老刑警劉巖刃泌,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凡壤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡耙替,警方通過查閱死者的電腦和手機(jī)亚侠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俗扇,“玉大人硝烂,你說我怎么就攤上這事⊥模” “怎么了钢坦?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵究孕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我爹凹,道長(zhǎng)厨诸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任禾酱,我火速辦了婚禮微酬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘颤陶。我一直安慰自己颗管,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布滓走。 她就那樣靜靜地躺著垦江,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搅方。 梳的紋絲不亂的頭發(fā)上比吭,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音姨涡,去河邊找鬼衩藤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涛漂,可吹牛的內(nèi)容都是我干的赏表。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼匈仗,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼瓢剿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悠轩,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤间狂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哗蜈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體前标,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年距潘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了炼列。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡音比,死狀恐怖俭尖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤稽犁,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布焰望,位于F島的核電站,受9級(jí)特大地震影響已亥,放射性物質(zhì)發(fā)生泄漏熊赖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一虑椎、第九天 我趴在偏房一處隱蔽的房頂上張望震鹉。 院中可真熱鬧,春花似錦捆姜、人聲如沸传趾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浆兰。三九已至,卻和暖如春珊豹,著一層夾襖步出監(jiān)牢的瞬間簸呈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工平夜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝶棋,地道東北人卸亮。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓忽妒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親兼贸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子段直,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355