Erlang 聊天室程序(九) 主题房间2 ---房间信息管理
接着上一篇,这次处理“维护当前可用的主题房间信息”问题。 每次使用startChild启动子进程的时候将当前的房间信息保存到ets表中。更重要的是每次主题房异常退出或重启都要更新对应的信息。
修改room_manager.erl中的内容:
新建一个函数来初始化房间信息表:
initTab()->
ets:new(roominfo,[public,
ordered_set,
named_table,
{keypos,#roominfo.id}
])
.
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)
.
#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
.
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)
.
#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
.
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
.
暂时不对代码进行测试,等后面整体修改完成后再一起测。
分类:
erlang
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述