[原理]
在时间和空间上面,我选择了以时间换空间的做法。
在struct.h中修改:
struct BCACHE {
struct shortfile bcache[ MAXBOARD ];
int number;
time_t uptime;
time_t pollvote;
time_t fresh_date;
char date[60];
time_t friendbook; /* friendbook mtime */
int inboard[MAXBOARD]; /* 增加这一行储存每个版的在线人数 */
};
原理还是比较简单的,用户进入版面,该版面的在线人数+1,离开版面,该版面-1
进入版面的函数是: bbs.c中的Read()
于是在Read()中修改为:
usetime = time(0);
/* inboard user count by ZV 2002.12.13 */
for (iPos=0; iPos<MAXBOARD; iPos++)
if (!strcmp(brdshm->bcache[iPos].filename, currboard)) {
brdshm->inboard[iPos]++;
break;
}
/* 进入版面 */
i_read(READING, buf, readtitle, readdoent, &read_comms[0],
sizeof(struct fileheader));
/* 退出版面 */
brdshm->inboard[iPos]--;
/* 统计时间 */
board_usage(currboard, time(0) - usetime);
离开版面的情况稍微有点复杂
1)正常离开:见上面bbs.c Read()函数的修改
2)非正常离开:客户主动断口连接,或者被人KICK掉。
这个时候服务器的bbsd会调用main.c的 abort_bbs()
将其修改为:
if (started) {
time_t stay;
stay = time(0) - login_start_time;
sprintf(genbuf, "Stay: %3ld (%s)", stay / 60, currentuser.username);
/* inboard user count by ZV 2002.12.13 */
if ((uinfo.mode == READING) || (uinfo.mode == POSTING) ||
(uinfo.mode == EDIT)) {
for (i=0; i<MAXBOARD; i++)
if (!strcmp(brdshm->bcache[i].filename, currboard)) {
if (brdshm->inboard[i]>0)
brdshm->inboard[i]--;
break;
}
}
log_usies("AXXED", genbuf);
u_exit();
}
注意:只有用户的状态是 READING, POSTING, EDIT之一才表示用户在版面内
还有一个版面显示的问题,这个比较灵活,我可以给一网深情的参考代码:
显示标题是在board.c的show_brdlist函数
prints
("^[[1;44;37m %s 未 讨论区名称 V 类别 转 %-25s S 板 主 在线 ^[[m\n",
newflag ? "全部" : "编号", "中 文 叙 述");
/* format modified by ZV 2002.12.12*/
}
move(3, 0);
for (n = page; n < page + BBS_PAGESIZE; n++) {
if (n >= brdnum) {
prints("\n");
continue;
}
ptr = &nbrd[n];
if (newflag) // for the num>10000 By ZV 2002.4.17
if (ptr->total == -1) {
refresh();
check_newpost(ptr);
}
/* inboard user count by ZV 2002.12.13 */
for (i=0; i<MAXBOARD; i++)
if (!strcmp(brdshm->bcache[i].filename, ptr->name)) {
inboard =brdshm->inboard[i];
break;
}
prints(" %5d %s", newflag ? ptr->total:n+1, ptr->unread ? "◆" : "◇");
strcpy(tmpBM, ptr->BM);
prints("%c%-12s%s %-35s %c %-12s%3d\n",
(ptr->zap && !(ptr->flag & NOZAP_FLAG)) ? '*' : ' ',
ptr->name,
(ptr->flag & VOTE_FLAG) ? "^[[1;31mV^[[m" : " ",
ptr->title + 1, HAS_PERM(PERM_POST) ? ptr->status : ' ',
ptr->BM[0] <= ' ' ? "诚征板主中" : strtok(tmpBM, " "),
inboard);
[问题]
简单加了一个功能,和其他数据操作配合不是很好。
由于MAXBOARD比较小,所以没有对查找进行任何优化。
仅仅利用了共享内存,但是却修改了bcache结构。
--
FROM 202.112.14.