接着上一篇,这次处理“维护当前可用的主题房间信息”问题。 每次使用startChild启动子进程的时候将当前的房间信息保存到ets表中。更重要的是每次主题房异常退出或重启都要更新对应的信息。
修改room_manager.erl中的内容:
新建一个函数来初始化房间信息表:
initTab()-> ets:new(roominfo,[public, ordered_set, named_table, {keypos,#roominfo.id} ]) .
再添加对房间表数据操作的方法
addRoomInfo(Record)-> #roominfo{name=Name,type=Type}=Record, case isRoomUniq([],Name,Type)of {found,_Id}-> {fail,room_exists}; {not_found}-> RoomId=id_generator:getnewid("room"), ClientTableName=list_to_atom(?PRIFIX++integer_to_list(RoomId)), Info=Record#roominfo{id=RoomId,tablename=ClientTableName}, ets:insert(roominfo, Info), {success,Info} end . setRoomAvailble(Id)-> case ets:lookup(roominfo, Id) of Record-> ets:update_element(roominfo, Id, {#roominfo.status,1}), ok; []-> ok end . setRoomUnavailble(Id)-> case ets:lookup(roominfo, Id) of Record-> ets:update_element(roominfo, Id, {#roominfo.status,0}), ok; []-> ok end . removeRoom(Id)-> ets:delete(roominfo, Id) .
为了方便后面的操作,再提供两个方法,一个根据给定的属性获取对应的ID,一个是判断对应ID的房间是否存在:
getRoomProperty(Id,Proper)-> case ets:lookup(roominfo, Id) of Record-> #roominfo{name=Name, type=Type, unum=Unum, tablename=Tab, status=Status, creationDate=Crdate}=Record, case Proper of #roominfo.name-> {ok,Name}; #roominfo.type-> {ok,Type}; #roominfo.unum-> {ok,Unum}; #roominfo.tablename-> {ok,Tab}; #roominfo.status-> {ok,Status}; #roominfo.creationDate-> {ok,Crdate}; _Els-> {fail,illegal_property} end; _Els-> {fail,not_found} end . isRoomUniq([],Name,Type)-> case ets:all(roominfo) of [R|L]-> #roominfo{id=Id,name=TheName,type=TheType}=R, case string:equal("Name",TheName) and string:equal(Type, TheType) of true-> {found,Id}; false-> isRoomUniq([L],Name,Type) end; []-> {not_found} end ; isRoomUniq([L],Name,Type)-> case ets:all(roominfo) of [R|L]-> #roominfo{id=Id,name=TheName,type=TheType}=R, case string:equal("Name",TheName) and string:equal(Type, TheType) of true-> {found,Id}; false-> isRoomUniq([L],Name,Type) end; []-> {not_found} end .
再修改chat_room的terminate,从表中删除相应的记录:
terminate(_Reason,State)-> #roominfo{id=Id}=State, room_manager:removeRoom(Id) .
再修改房间启动时的初始化方法,房间的ID和名称从外部传入:
init([Para])-> id_generator:start_link(), #roominfo{id=RoomId,tablename=ClientTableName}=Para, client_manager:init(ClientTableName), case is_record(Para,roominfo)of true-> {ok,#roominfo{unum=0}=Para,tablename=ClientTableName}; Els-> {ok,#roominfo{id=RoomId,unum=0,name="room"++integer_to_list(RoomId),tablename=ClientTableName,type="def"}} end .
暂时不对代码进行测试,等后面整体修改完成后再一起测。