Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
何 广一
chatroom
Commits
1776bb7a
Commit
1776bb7a
authored
Aug 26, 2025
by
何 广一
Browse files
created docker image
parent
9bf2ef80
Changes
9
Expand all
Show whitespace changes
Inline
Side-by-side
chat-room/.eslintrc.js
0 → 100644
View file @
1776bb7a
module
.
exports
=
{
ignorePatterns
:
[
'
src/generated/prisma/**
'
],
extends
:
[
'
next/core-web-vitals
'
],
rules
:
{},
};
\ No newline at end of file
chat-room/dockerfile
View file @
1776bb7a
...
...
@@ -3,7 +3,7 @@
FROM
node:20-alpine
AS
base
WORKDIR
/app
COPY
package.json pnpm-lock.yaml ./
RUN
npm
install
-g
pnpm
&&
pnpm
install
--frozen-lockfile
--shamefully-hoist
RUN
npm
install
-g
pnpm
&&
pnpm
install
--shamefully-hoist
# ---------- Prisma + SQLite ----------
COPY
prisma ./prisma
...
...
@@ -14,15 +14,17 @@ RUN pnpm prisma migrate deploy --schema ./prisma/schema.prisma
# ---------- 构建 ----------
COPY
. .
ENV
REDIS_URL=
RUN
pnpm build
# ---------- 运行时 ----------
FROM
node:20-alpine
AS
runner
WORKDIR
/app
RUN
apk add
--no-cache
redis
COPY
--from=base /app/.next ./.next
COPY
--from=base /app/node_modules ./node_modules
COPY
--from=base /app/package.json ./package.json
COPY
--from=base /app/.next/standalone ./
COPY
--from=base /app/.next/static ./.next/static
COPY
--from=base /app/public ./public
COPY
--from=base /app/prisma ./prisma
COPY
--from=base /app/.env.docker ./.env
...
...
chat-room/eslint.config.mjs
View file @
1776bb7a
...
...
@@ -11,6 +11,10 @@ const compat = new FlatCompat({
const
eslintConfig
=
[
...
compat
.
extends
(
"
next/core-web-vitals
"
,
"
next/typescript
"
),
{
ignores
:
[
"
src/generated/prisma/**
"
],
},
];
export
default
eslintConfig
;
chat-room/next.config.ts
View file @
1776bb7a
import
type
{
NextConfig
}
from
"
next
"
;
const
nextConfig
:
NextConfig
=
{
output
:
'
standalone
'
/* config options here */
};
...
...
chat-room/package.json
View file @
1776bb7a
...
...
@@ -10,6 +10,7 @@
"redis"
:
"start redis-server --port 6379"
},
"dependencies"
:
{
"@types/node"
:
"^20"
,
"@types/react"
:
"^19"
,
"@types/react-dom"
:
"^19"
,
"@prisma/client"
:
"6.14.0"
,
...
...
chat-room/pnpm-lock.yaml
View file @
1776bb7a
This diff is collapsed.
Click to expand it.
chat-room/src/app/api/room-api.tsx
View file @
1776bb7a
...
...
@@ -238,8 +238,8 @@ export async function AddMessage(data: Ty.MessageAddArgs): Promise<Ty.BackendRes
export
async
function
StartAuthSession
()
:
Promise
<
Ty
.
BackendResponse
<
Auth
.
Session
>>
{
const
sessionId
=
getRandomToken
();
redis
.
set
(
`Session:
${
sessionId
}
`
,
"
{}
"
);
redis
.
expire
(
`Session:
${
sessionId
}
`
,
60
*
5
);
// 5分钟内登录/注册有效
redis
?
.
set
(
`Session:
${
sessionId
}
`
,
"
{}
"
);
redis
?
.
expire
(
`Session:
${
sessionId
}
`
,
60
*
5
);
// 5分钟内登录/注册有效
return
{
code
:
0
,
...
...
@@ -252,7 +252,7 @@ export async function StartAuthSession() : Promise<Ty.BackendResponse<Auth.Sessi
export
async
function
Login
(
args
:
Auth
.
AuthArgs
)
:
Promise
<
Ty
.
BackendResponse
<
Auth
.
LoginResult
|
null
>>
{
const
{
sessionId
,
username
,
password
,
userAgent
,
userIP
}
=
args
;
const
sessionStr
=
await
redis
.
get
(
`Session:
${
sessionId
}
`
);
const
sessionStr
=
await
redis
?
.
get
(
`Session:
${
sessionId
}
`
);
if
(
!
sessionStr
)
{
return
{
...
...
@@ -289,7 +289,7 @@ export async function Login(args: Auth.AuthArgs) : Promise<Ty.BackendResponse<Au
}
});
await
redis
.
del
(
`Session:
${
sessionId
}
`
);
await
redis
?
.
del
(
`Session:
${
sessionId
}
`
);
return
{
code
:
0
,
...
...
@@ -337,7 +337,7 @@ export async function AutoLogin(args: Auth.AutoLoginArgs) : Promise<Ty.BackendRe
export
async
function
Register
(
args
:
Auth
.
AuthArgs
)
:
Promise
<
Ty
.
BackendResponse
<
Auth
.
RegisterResult
|
null
>>
{
const
{
sessionId
,
username
,
password
}
=
args
;
const
sessionStr
=
await
redis
.
get
(
`Session:
${
sessionId
}
`
);
const
sessionStr
=
await
redis
?
.
get
(
`Session:
${
sessionId
}
`
);
if
(
!
sessionStr
)
{
return
{
...
...
@@ -372,7 +372,7 @@ export async function Register(args: Auth.AuthArgs) : Promise<Ty.BackendResponse
}
});
await
redis
.
del
(
`Session:
${
sessionId
}
`
);
await
redis
?
.
del
(
`Session:
${
sessionId
}
`
);
return
{
code
:
0
,
...
...
chat-room/src/app/chat/page.tsx
View file @
1776bb7a
...
...
@@ -6,10 +6,12 @@ import UsernameCheck from './username-check';
import
PageHeaderProvider
from
'
./header
'
import
ConfirmModalProvider
from
'
./confirm-modal
'
;
import
{
RoomProvider
}
from
'
./room-context
'
import
{
Suspense
}
from
'
react
'
;
export
default
function
Home
()
{
return
(
<
Suspense
fallback
=
{
<
div
>
Loading...
</
div
>
}
>
<
RoomProvider
>
<
UsernameCheck
/>
<
ConfirmModalProvider
/>
...
...
@@ -28,5 +30,6 @@ export default function Home() {
</
div
>
</
div
>
</
RoomProvider
>
</
Suspense
>
);
}
chat-room/src/lib/db.ts
View file @
1776bb7a
...
...
@@ -8,14 +8,20 @@ declare global{
var
rateLimiter
:
RateLimiterRedis
|
undefined
;
}
const
connectRedisClient
=
async
()
=>
{
const
client
=
createClient
();
client
.
on
(
'
error
'
,
(
err
)
=>
console
.
error
(
'
Redis Client Error
'
,
err
));
await
client
.
connect
();
const
isBuild
=
process
.
env
.
NEXT_PHASE
===
'
phase-production-build
'
;
const
client
=
isBuild
?
undefined
:
createClient
();
client
?.
on
(
'
error
'
,
(
err
)
=>
console
.
error
(
'
Redis Client Error
'
,
err
));
await
client
?.
connect
();
return
client
;
};
const
getRateLimiter
=
()
=>
{
const
isBuild
=
process
.
env
.
NEXT_PHASE
===
'
phase-production-build
'
;
if
(
isBuild
)
return
undefined
;
const
rateLimiter
=
new
RateLimiterRedis
({
storeClient
:
redis
,
keyPrefix
:
'
rateLimiter
'
,
...
...
@@ -25,6 +31,8 @@ const getRateLimiter = () => {
return
rateLimiter
;
};
export
const
prisma
=
global
.
prisma
||
new
PrismaClient
();
export
const
redis
=
global
.
redisClient
||
await
connectRedisClient
();
export
const
rateLimiter
=
global
.
rateLimiter
||
getRateLimiter
();
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment