Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ac57ecc
prototype: implement JavaScript client for Mesh v2
takaokouji Dec 21, 2025
6c54936
fix: resolve JavaScript errors in prototype client
takaokouji Dec 21, 2025
f6c02a4
fix: enable Join Selected Group button when group is selected
takaokouji Dec 21, 2025
67d4b7b
fix: correct GraphQL mutations to match backend schema
takaokouji Dec 21, 2025
bbf056e
fix: correct Event type field names in fireEventByNode
takaokouji Dec 21, 2025
459ac5f
feat: implement polling-based subscription for other nodes data
takaokouji Dec 21, 2025
d210b03
feat: implement real WebSocket subscriptions with AWS Amplify
takaokouji Dec 21, 2025
336e937
feat: implement missing GraphQL query methods
takaokouji Dec 21, 2025
d2ed3ab
fix: use esbuild to bundle AWS Amplify dependencies
takaokouji Dec 21, 2025
26197eb
fix: replace inline onclick with programmatic event listeners
takaokouji Dec 21, 2025
f43f281
fix: move setInterval into DOMContentLoaded handler
takaokouji Dec 21, 2025
68d937b
fix: send initial sensor data when joining/creating group
takaokouji Dec 21, 2025
5b0b5c4
fix: make subscription return types nullable to prevent null errors
takaokouji Dec 21, 2025
8ef1412
docs: update comments for initial sensor data in prototype
takaokouji Dec 21, 2025
ecb0ace
feat: implement subscription E2E tests and listGroupStatuses resolver
takaokouji Dec 21, 2025
650d810
fix: implement event subscription and prevent duplicate event history…
takaokouji Dec 22, 2025
f251bd8
feat: add disconnect button and fix session timer in prototype
takaokouji Dec 22, 2025
ec63ccd
style: fix Ruby string literals to use double quotes (StandardRB)
takaokouji Dec 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,36 @@ All resources are automatically tagged. Use tags for:
- Resource grouping
- Environment identification

### 7. Ruby String Literals

Always use double-quoted strings in Ruby code to maintain consistency with StandardRB style:

```ruby
# Good
require "json"
require "aws-sdk-dynamodb"

message = "Hello, world!"
interpolation = "Value: #{variable}"
symbol = :"my-symbol"

# Bad
require 'json'
require 'aws-sdk-dynamodb'

message = 'Hello, world!'
interpolation = 'Value: #{variable}'
symbol = :'my-symbol'
```

**Rationale**:
- Consistent with StandardRB linter rules
- Double quotes support interpolation without changes
- Reduces cognitive overhead in code reviews
- Aligns with Ruby community best practices

Run `bundle exec standardrb` to check for violations and `bundle exec standardrb --fix` to auto-fix.

## GraphQL Schema Notes

### Key Types
Expand Down
214 changes: 214 additions & 0 deletions SUBSCRIPTION_DEBUG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
# Subscription Debug Guide

## 問題

別デバイスのsubscriptionにsensor dataの変更が反応しない。

## 調査結果

### ✅ 確認済み(正常)

1. **GraphQLスキーマの設定**
```graphql
type Subscription {
onDataUpdateInGroup(groupId: ID!, domain: String!): NodeStatus
@aws_subscribe(mutations: ["reportDataByNode"])
}
```
- `@aws_subscribe` directive が正しく設定されている
- mutation名 `reportDataByNode` が一致している

2. **NodeStatus型の定義**
```graphql
type NodeStatus {
nodeId: ID!
groupId: ID! # ✓ subscription filtering に必要
domain: String! # ✓ subscription filtering に必要
data: [SensorData!]!
timestamp: AWSDateTime!
}
```
- `groupId` と `domain` フィールドが含まれている(filtering用)

3. **Mutation Resolver (reportDataByNode)**
- `js/resolvers/Mutation.reportDataByNode.js`
- DynamoDBへの書き込みが正常に動作
- `groupId` と `domain` を含むNodeStatusを返している

4. **AppSync Logging**
- CloudWatch Logsで確認
- `reportDataByNode` mutationが正常に実行されている
- エラーログなし

5. **Subscription Query**
- `mesh-client.js` のsubscription queryが正しい
- `groupId` と `domain` を変数として渡している
- 結果セットに `groupId` と `domain` を含めている

### ❓ 未確認(要デバッグ)

1. **Subscription接続の持続性**
- WebSocket接続がタイムアウトしていないか
- Amplifyのsubscription reconnect動作

2. **AppSyncのsubscription publish**
- CloudWatch Logsにsubscription publishログが出力されているか
- Filteringが正しく動作しているか

3. **ブラウザ側の受信**
- `console.log('Subscription data received:')` が出力されているか
- Network tabでWebSocket通信が確認できるか

## デバッグ手順

### Method 1: デバッグツールを使用

1. **デバッグツールを開く**
```bash
cd examples/javascript-client
npm start
# Open http://localhost:3000/debug-subscription.html
```

2. **グループIDを準備**
- メインプロトタイプ (http://localhost:3000) でグループを作成
- グループIDをコピー

3. **デバッグツールで確認**
- Group IDを入力
- "1. Subscribe to onDataUpdateInGroup" をクリック
- "2. Send Sensor Data" をクリック
- ログに "SUBSCRIPTION DATA RECEIVED!" が表示されるか確認

### Method 2: ブラウザ2窓テスト

1. **Window 1: ホスト**
```
http://localhost:3000?mesh=test-domain
```
- グループ作成
- ブラウザDevTools → Console を開く

2. **Window 2: メンバー**
```
http://localhost:3000?mesh=test-domain
```
- 同じグループに参加
- ブラウザDevTools → Console を開く
- ブラウザDevTools → Network タブで "WebSocket" フィルタを確認

3. **Window 1でセンサーデータ送信**
- Temperatureスライダーを動かす
- Console に "Sensor data sent:" が表示される

4. **Window 2で受信確認**
- Console に "Subscription data received:" が表示されるか確認
- Network tab で WebSocket メッセージを確認

### Method 3: CloudWatch Logs監視

```bash
# AppSyncログをリアルタイム監視
aws logs tail /aws/appsync/apis/2kw5fyno4bhjbc47mvu3rxytye --follow
```

**確認ポイント:**
1. Subscription接続ログ
2. reportDataByNode実行ログ
3. Subscription publishログ(これが重要!)

### Method 4: 統合テスト

```bash
cd /Users/kouji/work/smalruby/smalruby3-develop/infra/mesh-v2

# Subscription関連テスト実行
export APPSYNC_ENDPOINT=https://rb6mjlr72rhudiztdmfvoyctbq.appsync-api.ap-northeast-1.amazonaws.com/graphql
export APPSYNC_API_KEY=da2-kp6w6skjfjgpxb7ufwt25zophm

bundle exec rspec spec/requests/subscription_realtime_spec.rb --format documentation
```

## 予想される問題と解決策

### 問題1: WebSocket接続のタイムアウト

**症状:** Subscriptionを確立した数分後にmutationを実行しても反応しない

**原因:** AppSync WebSocket接続のデフォルトタイムアウト

**解決策:**
- Amplifyの reconnect設定を確認
- Keep-aliveメカニズムの実装

### 問題2: Subscription Filteringの不一致

**症状:** Mutationは成功するがsubscriptionに届かない

**原因:**
- subscription変数の `groupId`/`domain` とmutation結果の値が一致していない
- 大文字小文字の違い
- 余分な空白

**デバッグ:**
```javascript
// mesh-client.js の subscribeToDataUpdates に追加
console.log('Subscribing with variables:', { groupId, domain });

// app.js の sendSensorData に追加
console.log('Sending data to:', {
groupId: state.currentGroup.id,
domain: state.currentGroup.domain
});
```

### 問題3: AppSync @aws_subscribe の設定ミス

**症状:** Subscriptionが一切反応しない

**確認:**
```bash
# スキーマを確認
cat graphql/schema.graphql | grep -A 3 "onDataUpdateInGroup"

# 期待される出力:
# onDataUpdateInGroup(groupId: ID!, domain: String!): NodeStatus
# @aws_subscribe(mutations: ["reportDataByNode"])
```

### 問題4: Amplifyのバージョン互換性

**症状:** Subscription接続はできるが、データが届かない

**確認:**
```bash
cd examples/javascript-client
npm list aws-amplify
```

**解決策:** AWS Amplify v6を使用(現在使用中)

## 次のステップ

1. **デバッグツール (`debug-subscription.html`) を使用して動作確認**
- Subscriptionが正しく確立されるか
- Mutationがsubscriptionをトリガーするか

2. **CloudWatch Logsでsubscription publish確認**
- AppSyncがsubscriptionにpublishしているか
- Filteringが正しく動作しているか

3. **必要に応じてコード修正**
- Logging追加
- Reconnect処理追加
- Error handling改善

## 参考リンク

- [AWS AppSync Subscriptions](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)
- [AWS Amplify Subscriptions](https://docs.amplify.aws/javascript/build-a-backend/graphqlapi/subscribe-data/)
- [@aws_subscribe Directive](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-directives.html#aws-subscribe)

---

**Last Updated:** 2025-12-22
3 changes: 3 additions & 0 deletions examples/javascript-client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
mesh-client.bundle.js
mesh-client.bundle.js.map
Loading
Loading